RFC 4843
An IPv6 Prefix for Overlay Routable Cryptographic Hash Identifiers (ORCHID)
An IPv6 Prefix for Overlay Routable Cryptographic Hash Identifiers (ORCHID) ๐ฆ
okay bestie, this RFC is an Experimental one from April 2007 ๐ธ (so it's not an Internet standard, just an experiment the community is poking at ๐งช). The main authors are P. Nikander from Ericsson Research Nomadic Lab, J. Laganier from DoCoMo Euro-Labs, and F. Dupont from CELAR. The title block doesn't list any RFCs that it obsoletes or updates, so it's not changing anything that came before ๐
Status of This Memo
This memo defines an Experimental Protocol for the Internet community โจ. It is not an Internet standard of any kind, and the authors are asking everyone to chime in with discussion and suggestions for making it better ๐ซถ. Distribution of this memo is unlimited ๐
Copyright Notice
Copyright (C) The IETF Trust (2007) ยฉ๏ธ๐
Abstract
okay so this document introduces Overlay Routable Cryptographic Hash Identifiers (ORCHID) ๐ฎ, a brand new experimental class of identifiers that look like IPv6 addresses ๐ญ. They're meant to be endpoint identifiers used by applications and Application Programming Interfaces (API), NOT locators for network location at the IP layer ๐ โโ๏ธ. They're designed to show up as application layer entities and inside the existing IPv6 APIs, but they should not appear in actual IPv6 headers ๐. To make them feel more like regular IPv6 addresses, they're expected to be routable at an overlay level ๐ฆ. So even though they count as non-routable from the IPv6 layer's point of view, all existing IPv6 applications are expected to be able to use them in a way that's compatible with current IPv6 addresses. main character energy ๐
This document also asks IANA to allocate a temporary prefix out of the IPv6 addressing space for ORCHIDs ๐. By default, the prefix gets returned to IANA in 2014, and continued use requires IETF consensus ๐ (so it's not forever, babe ๐).
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Rationale and Intent . . . . . . . . . . . . . . . . . . . 3
1.2. ORCHID Properties . . . . . . . . . . . . . . . . . . . . 4
1.3. Expected use of ORCHIDs . . . . . . . . . . . . . . . . . 4
1.4. Action Plan . . . . . . . . . . . . . . . . . . . . . . . 4
1.5. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4
2. Cryptographic Hash Identifier Construction . . . . . . . . . . 5
3. Routing Considerations . . . . . . . . . . . . . . . . . . . . 6
3.1. Overlay Routing . . . . . . . . . . . . . . . . . . . . . 6
4. Collision Considerations . . . . . . . . . . . . . . . . . . . 7
5. Design Choices . . . . . . . . . . . . . . . . . . . . . . . . 9
6. Security Considerations . . . . . . . . . . . . . . . . . . . 9
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10
8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 11
9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 11
9.1. Normative References . . . . . . . . . . . . . . . . . . . 11
9.2. Informative References . . . . . . . . . . . . . . . . . . 11
1. Introduction โจ
bestie, this is where it starts ๐ธ. This document introduces ORCHIDs, a new class of IP address-like identifiers ๐ง. They're meant to be globally unique in a statistical sense (see Section 4) ๐ฒ, non-routable at the IP layer ๐ซ, and routable at some overlay layer ๐ฆ. They're securely bound, using a secure hash function, to the concatenation of an input bitstring and a context tag ๐. Typically, but not necessarily, the input bitstring will include a suitably encoded public cryptographic key ๐๏ธ (the "typically but not necessarily" part is giving careful ๐).
1.1. Rationale and Intent
so ORCHIDs are expected to be used at the existing IPv6 Application Programming Interfaces (API) and application protocols between consenting hosts ๐ซถ. They can be defined and used in different contexts, suitable for different overlay protocols ๐. Examples include Host Identity Tags (HIT) in the Host Identity Protocol (HIP) [HIP-BASE] and Temporary Mobile Identifiers (TMI) for Mobile IPv6 Privacy Extension [PRIVACYTEXT] ๐.
since these identifiers are going to be used alongside IPv6 addresses at both applications and APIs, coordination is desired so that an ORCHID doesn't get mistaken for a vanilla IPv6 address, and vice versa ๐. In practice, allocating a separate prefix for ORCHIDs seems to do the trick ๐ . That makes them compatible with IPv6 addresses at the upper layers while also making it super easy to stop them from being used at the IP layer โจ.
ngl, using ORCHIDs between consenting hosts without any coordination with the IETF and the IANA is technically possible ๐ฌ, but the authors would consider that practice potentially dangerous ๐จ. A specific danger would show up if the IETF community later decided to use the ORCHID prefix for some different purpose ๐. In that case, hosts using the ORCHID prefix would, for practical purposes, be unable to use the prefix for that new purpose. That would lead to partial balkanisation of the Internet ๐งฑ, kind of like what happened when non-RFC 1918 [RFC1918] IPv4 addresses got hijacked for private use over the years ๐. Not it ๐ โโ๏ธ.
the whole need for the proposed allocation comes from wanting to use ORCHIDs with existing applications and APIs ๐ฅน. That desire creates the potential conflict mentioned above, and resolving the conflict requires the proposed allocation ๐.
okay, real talk: one can argue that wanting to use these kinds of identifiers through existing APIs is architecturally wrong, and honestly, there's some truth in that ๐ค. It would be more desirable to introduce a new API and update all applications to use identifiers, rather than locators, through that new API ๐. That's exactly what the authors expect to happen in the long run ๐ฎ.
BUT, given the current state of the Internet, they don't think it's viable to introduce any changes that, all at once, require applications to be rewritten and host stacks to be updated ๐ญ. Instead, they believe in piece-wise architectural changes that only touch one of the existing assets ๐งฉ. ORCHIDs are designed to address this situation: letting people experiment with protocol stack extensions, such as secure overlay routing, HIP, or Mobile IP privacy extensions, without needing to update their applications ๐ฆ. The goal is to make large-scale experiments possible with minimum user effort โญ.
for example, at the time of writing, there already exist HIP implementations that run fully in user space ๐. They use the operating system to divert a certain part of the IPv6 address space to a user level daemon for HIP processing ๐ง. In practical terms, these implementations are already using a certain IPv6 prefix to tell HIP identifiers apart from IPv6 addresses, which lets both be used by existing applications through existing APIs ๐ธ.
this document argues for allocating an experimental prefix for these purposes, which paves the way for large-scale experiments with cryptographic identifiers without the dangers caused by address-space hijacking ๐๐ซถ.
1.2. ORCHID Properties
ORCHIDs are designed to have the following properties ๐:
- Statistical uniqueness; also see Section 4
- Secure binding to the input parameters used in their generation (i.e., the context identifier and a bitstring).
- Aggregation under a single IPv6 prefix. Note that this is only needed due to the coordination need as indicated above. Without such coordination need, the ORCHID namespace could potentially be completely flat ๐ฅ.
- Non-routability at the IP layer, by design ๐ซ.
- Routability at some overlay layer, making them, from an application point of view, semantically similar to IPv6 addresses ๐ฆ.
as mentioned above, ORCHIDs are meant to be generated and used in different contexts, depending on what suits different mechanisms and protocols ๐. The context identifier is used to tell those contexts apart ๐ท๏ธ. See Section 4 for a discussion of the related API and kernel level implementation issues, and Section 5 for the design choices explaining why the context identifiers are used ๐ง โจ.
1.3. Expected use of ORCHIDs
examples of identifiers and protocols that are expected to adopt the ORCHID format include Host Identity Tags (HIT) in the Host Identity Protocol [HIP-BASE], and the Temporary Mobile Identifiers (TMI) in the Simple Privacy Extension for Mobile IPv6 [PRIVACYTEXT] ๐. The format is designed to be extensible, so other experimental proposals can share the same namespace ๐๐ซง.
1.4. Action Plan
this one's simple, babe ๐ : this document requests IANA to allocate an experimental prefix out of the IPv6 addressing space for Overlay Routable Cryptographic Hash Identifiers ๐.
1.5. Terminology
the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] ๐๐. Those are the capital-letter rules, so pay attention to them ๐๐ซถ.
2. Cryptographic Hash Identifier Construction โจ
okay so an ORCHID gets generated with the algorithm below ๐ it takes a bitstring plus a context identifier as input and spits out an ORCHID ๐ฆ
Input := any bitstring
Hash Input := Context ID | Input
Hash := Hash_function( Hash Input )
ORCHID := Prefix | Encode_100( Hash )
here's what each piece means ๐
|is concatenation of bitstrings ๐Inputis a bitstring that's unique or statistically unique within a given context. it's meant to be tied to the ORCHID being created in that context ๐ธContext IDis a randomly generated value. it defines the expected usage context for a particular ORCHID, and it also picks the hash function used for generating ORCHIDs in that context. these values get allocated out of the namespace introduced for CGA Type Tags. see RFC 3972 and http://www.iana.org/assignments/cga-message-types ๐งHash_functionis the one-way hash function (meaning one with pre-image resistance and second pre-image resistance). it's the one named in the document that defines the context usage identified by theContext ID. for example, the current HIP specification uses SHA1 [RFC3174] to generate the ORCHIDs used in the HIP protocol [HIP-BASE] ๐ฅEncode_100( )is an extraction function. its output is the middle 100-bit-long bitstring of the argument bitstring ๐Prefixis a constant 28-bit-long bitstring value, which is2001:10::/28๐
to make an ORCHID you need two pieces of input data ๐ซถ the first can be any bitstring, but it's usually expected to hold a public cryptographic key plus some other data. the second is a context identifier, a 128-bit-long datum allocated the way Section 7 describes. every specific experiment (like HIP HITs or MIP6 TMIs) is expected to allocate its own context identifier ๐
the input bitstring and context identifier get concatenated into one input datum. that datum goes into the cryptographic hash function from the document defining that context usage. the hash result goes through the encoding function, which gives a 100-bit-long value. then the 28-bit ORCHID prefix gets stuck on the front ๐ the final result is the ORCHID: a 128-bit-long bitstring you can use at the IPv6 APIs on hosts in that particular experiment โจ
the ORCHID prefix sits inside the IPv6 global unicast address block, so ORCHIDs look exactly like IPv6 global unicast addresses ๐ BUT ngl, they don't follow the IPv6 global unicast address format from Section 2.5.4 of [RFC4291], because they don't have a 64-bit Interface ID formatted the way Section 2.5.1. of [RFC4291] describes ๐ it should be noted, so nobody gets confused!
3. Routing Considerations ๐ฆ
ORCHIDs are built to be location independent endpoint-identifiers, not IP-layer locators ๐ธ so routers MAY be configured not to forward any packet that has an ORCHID as its source or destination address. if the destination is an ORCHID but the source is a valid unicast source address, routers MAY be configured to send back an ICMP Destination Unreachable, Administratively Prohibited message:
ICMP Destination Unreachable, Administratively Prohibited
because ORCHIDs are experimental, router software MUST NOT include any special handling code for them ๐ซ in other words, if the non-routability property of ORCHIDs gets implemented, it MUST be done through configuration and not through hardwired software code. right now it's RECOMMENDED that the default router configuration doesn't handle ORCHIDs in any special way ๐ so there's no need to touch existing or new routers for this experiment. if a reason pops up later (say, a buggy implementation leaking ORCHIDs into the IP layer), the prefix can and should be blocked with one simple configuration rule ๐ก๏ธ
3.1. Overlay Routing ๐
as I keep saying, ORCHIDs are designed to be non-routable at the IP layer ๐ but there's a bunch of research happening on overlay routing and resolution for flat identifiers. two examples are the Host Identity Indirection Infrastructure (Hi3) [Hi3] and the Node Identity Internetworking Architecture (NodeID) [NodeID] proposals. they outline ways to use a Distributed Hash Table to forward HIP packets based on the Host Identity Tag ๐ง
what all these research proposals have in common is that they build a new kind of resolution or routing infrastructure on top of the existing Internet routing structure ๐๏ธ practically speaking, they deliver packets based on flat, non-routable identifiers by using info stored in a distributed database, usually one based on Distributed Hash Tables. that basically makes a whole new routing network on top of the existing IP-based one, one that can route packets addressed by identifiers that aren't IP addresses ๐ฎ
the typical benefits of overlay routing are location independence, multicast, anycast, and multihoming support that's more scalable than IP's, and better DoS resistance than the vanilla Internet ๐ช the main downside is usually performance that's an order of magnitude slower, because you end up with a pretty big number of extra lookup or forwarding steps ๐ญ so most of the time, the overlay routing system only gets used during initial protocol state set-up (cf. TCP handshake). after that, the endpoints just swap packets directly over IP and skip the overlay network entirely ๐
the net result of the typical overlay approaches is a communication service whose basic functionality is comparable to classical IP, but with way better resilience than vanilla IP in dynamic networking environments ๐ซง some experiments also add extra features, like stronger security or the ability to route through several IP addressing domains ๐
the authors expect ORCHIDs to become fully routable, through one or more overlay systems, before the end of the experiment โญ
4. Collision Considerations ๐
as noted above, the goal is for ORCHIDs to be globally unique in a statistical sense ๐ฏ meaning: if you have the ORCHID for one entity, the chance that the same ORCHID is used for a different entity somewhere else on the Internet has to be low enough to ignore for most practical purposes. we think the design hits that goal (see Section 5) โจ
now the very rare case where one ORCHID ends up referring to two different entities at the same time, in two different places on the Internet ๐ฑ even then, the chance of that becoming visible (and therefore something to deal with) at any single location is negligible. for the vast majority of cases, the two simultaneous uses will never cross paths ๐ still, rare doesn't mean impossible, so collisions can happen. this section gives sensible guidelines for softening the damage if one does ๐ฉน
as mentioned above, ORCHIDs are expected to be used at the legacy IPv6 APIs between consenting hosts ๐ค the context ID is meant to tell apart the various experiments, or contexts, that share the ORCHID namespace. BUT the context ID isn't in the ORCHID itself; it only shows up in front of the input bitstring as hash function input. that can cause some implementation complications, but we think the trade-off is worth it, since making the hash result part of an ORCHID longer more than pays off the cost ๐
because ORCHIDs aren't routable at the IP layer, sending packets with ORCHIDs at the API level means the sending host needs extra overlay state inside its stack. that state decides which parameters (like which locators) go in the outgoing packet ๐งญ an underlying assumption, and a fact in every proposal the authors know about, is that there's an overlay protocol for setting up and maintaining that extra state. the state-set-up protocol is assumed to carry the input bitstring, and the resulting ORCHID-related state in the stack has to be linkable back to the right context and state-set-up protocol ๐
even though ORCHID collisions are expected to be super rare, two kinds can still happen ๐ฌ
- first, two different input bitstrings in the same context might map to the same ORCHID. in that case, the state-set-up mechanism is expected to resolve the conflict, for example by telling the peer that the ORCHID is already in use ๐คทโโ๏ธ
- second, two input bitstrings used in different usage contexts might map to the same ORCHID. the main confusion here is about which context to use ๐
to prevent the second type, it's RECOMMENDED that implementations supporting multiple contexts at once keep a node-wide unified database of known ORCHIDs. then they should flag a conflict whenever any mechanism tries to register an ORCHID that's already taken ๐ง for example, if an ORCHID is already being used as a HIT in HIP, it can't also be used as a TMI in Mobile IP. if Mobile IP tries to use it, the kernel tells Mobile IP that the ORCHID is already in use ๐ โโ๏ธ
5. Design Choices ๐
this namespace's design has two competing forces pulling it in different directions ๐ฅ
- as many bits as possible should be kept for the hash result.
- it should be possible for multiple mechanisms to share the namespace.
wanting a long hash result means the prefix has to be as short as possible, with few (if any) bits spent on extra encoding. this design takes that to the max: every bit beyond the prefix is hash output ๐ฏ which leaves no bits in the ORCHID itself for identifying the context. plus, because of security considerations, the design REQUIRES the hash function used to build ORCHIDs to be constant; see Section 6 ๐
the authors explicitly thought about adding a hash-extension mechanism like the one in CGA [RFC3972], but decided to leave it out ๐ there were two reasons: they wanted simplicity, and the IPR situation around the hash-extension mechanism was somewhat unclear. if there's a future revision of this document, we strongly advise the future authors to reconsider that decision ๐
the wish to let multiple mechanisms share the namespace got handled by putting the context identifier into the hash function input ๐งฉ that doesn't let you directly infer the mechanism from an ORCHID. but it does let you verify, with high probability, that a given input bitstring and ORCHID belong to a given context. also see Section 6 ๐ธ
6. Security Considerations โจ
okay bestie, this section is where the ORCHID crew gets serious about keeping things secure ๐๐ ORCHIDs are designed to be securely bound to the Context ID and to the bitstring that goes in as the input parameters when they get generated ๐ฆ To pull that off, the generation algorithm leans on the second-preimage resistance property of the hash function (the one-way property, aka a.k.a. one-way) used to build them, see [RFC4270] ๐ง And to keep that property strong and dodge collisions, the allocated prefix needs to be as short as possible so there are as many bits as possible left for the hash output ๐
For a given Context ID, every mechanism that uses ORCHIDs MUST use exactly the same mechanism for generating an ORCHID from the input bitstring ๐จ Letting different mechanisms in without explicitly encoding the mechanism in the Context ID or in the ORCHID itself would open the door to so-called bidding-down attacks ๐ Here's the spicy part: if multiple different hash functions were allowed to build ORCHIDs valid for the same Context ID, and one of those hash functions got insecure, attackers could go after even the ORCHIDs built with the other, still-secure hash functions for that same Context ID ๐ญ
Because the crew wants to keep the hash output as long as possible, the hash function is NOT encoded in the ORCHID itself. It lives in the Context ID instead ๐ธ So the present design allows only one method per given Context ID for constructing ORCHIDs from input bitstrings ๐ If other methods are needed later (maybe ones using more secure hash functions), they MUST use a different Context ID ๐ซถ Which means the suggested move when the hash result gets too short (thanks to more computational power) or when the hash function becomes insecure (thanks to advances in cryptology) is to allocate a new Context ID and retire the current one โจ
As of today, SHA1 [RFC3174] is considered to satisfy the second-preimage resistance requirement ๐ The current version of the HIP specification defines SHA1 [RFC3174] as the hash function used to generate ORCHIDs for the Context ID used by the HIP protocol [HIP-BASE] ๐
To keep the collision probability low enough (see Section 4), each method MUST use a mechanism that makes sure the distinct input bitstrings are either unique or statistically unique within that context ๐ There are several ways to do this. For example, you can include a globally maintained counter value in the input bitstring, a pseudo-random number with sufficient entropy (minimum 100 bits), or a randomly generated public cryptographic key ๐ฅ The Context ID makes sure input bitstrings from different contexts never overlap ๐ฆ Together, these make sure the collision probability is determined only by the natural collision probability in the hash space, and is not increased by the possibility of colliding input bitstrings ๐
7. IANA Considerations ๐
okay so IANA handed out a temporary non-routable 28-bit prefix from the IPv6 address space ๐ธ By default, the prefix goes back to IANA in 2014, and continued use requires IETF consensus ๐ As per [RFC4773], the 28-bit prefix was pulled from the IANA Special Purpose Address Block, namely 2001:0000::/23, to support the experimental usage described in this document โจ IANA has updated the IPv6 Special Purpose Address Registry ๐
During the discussions for this document, people suggested that other identifier spaces might get allocated from this block later ๐ However, this document does NOT define such a policy or any such allocations ๐ซ
The Context Identifier (or Context ID) is a randomly generated value that defines the usage context of an ORCHID and the hash function used to generate ORCHIDs in that context ๐ง This document defines no specific value ๐
We propose sharing the name space introduced for CGA Type Tags ๐ซถ So defining new values would follow the rules of Section 8 of [RFC3972], which means First Come First Served ๐
8. Acknowledgments ๐
Special thanks to Geoff Huston for his sharp but constructive critique while this memo was being developed ๐ Tom Henderson helped clear up a bunch of issues ๐ This document also got better thanks to reviews, comments, and discussions from the IPv6, Internet Area, and IETF communities ๐ซถ
Julien Laganier is partly funded by Ambient Networks, a research project supported by the European Commission under its Sixth Framework Program ๐ช๐บ The views and conclusions in here are those of the authors and should not be read as necessarily representing the official policies or endorsements, either expressed or implied, of the Ambient Networks project or the European Commission ๐
9. References ๐
9.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC3972] Aura, T., "Cryptographically Generated Addresses
(CGA)", RFC 3972, March 2005.
9.2. Informative References
[HIP-BASE] Moskowitz, R., "Host Identity Protocol", Work
in Progress, February 2007.
[Hi3] Nikander, P., Arkko, J., and B. Ohlman, "Host Identity
Indirection Infrastructure (Hi3)", November 2004.
[NodeID] Ahlgren, B., Arkko, J., Eggert, L., and J. Rajahalme,
"A Node Identity Internetworking Architecture
(NodeID)", April 2006.
[PRIVACYTEXT] Dupont, F., "A Simple Privacy Extension for Mobile
IPv6", Work in Progress, July 2006.
[RFC1918] Rekhter, Y., Moskowitz, R., Karrenberg, D., Groot, G.,
and E. Lear, "Address Allocation for Private
Internets", BCP 5, RFC 1918, February 1996.
[RFC3174] Eastlake, D. and P. Jones, "US Secure Hash Algorithm 1
(SHA1)", RFC 3174, September 2001.
[RFC4270] Hoffman, P. and B. Schneier, "Attacks on Cryptographic
Hashes in Internet Protocols", RFC 4270,
November 2005.
[RFC4291] Hinden, R. and S. Deering, "IP Version 6 Addressing
Architecture", RFC 4291, February 2006.
[RFC4773] Huston, G., "Administration of the IANA Special
Purpose IPv6 Address Block", RFC 4773, December 2006.
Authors' Addresses ๐ฆ
Pekka Nikander
Ericsson Research Nomadic Lab
JORVAS FI-02420
Finland
Phone: +358 9 299 1
EMail: pekka.nikander@nomadiclab.com
Julien Laganier
DoCoMo Communications Laboratories Europe GmbH
Landsberger Strasse 312
Munich 80687
Germany
Phone: +49 89 56824 231
EMail: julien.ietf@laposte.net
Francis Dupont
CELAR
EMail: Francis.Dupont@fdupont.fr
Full Copyright Statement โญ
Copyright (C) The IETF Trust (2007).
This document is subject to the rights, licenses and restrictions
contained in BCP 78, and except as set forth therein, the authors
retain all their rights.
This document and the information contained herein are provided on an
"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND
THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property ๐
The IETF takes no position on the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document, or on the extent to which any license under such rights might or might not be available. It also doesn't claim to have made any independent effort to identify any such rights. Info about the procedures for rights in RFC documents can be found in BCP 78 and BCP 79 ๐
Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses to be made available, or the result of an attempt to get a general license or permission for implementers or users to use these proprietary rights can be found in the IETF's online IPR repository at:
http://www.ietf.org/ipr
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology needed to implement this standard. Please send that info to the IETF at:
ietf-ipr@ietf.org
Acknowledgement ๐
Funding for the RFC Editor function is currently provided by the Internet Society ๐ธ
๐ฆ where this page comes from
- ietf: rfc4843 2007-04
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms