I've been using something similar for ORCHIDv2-ish addressing, q.v. [1].

from base64 import b64decode
from hashlib import shake_128
from ipaddress import IPv6Network

public_key = b64decode(...)
secret = "somesecret".encode('utf-8')
network = IPv6Network("2001:20::/28")

hash = shake_128(secret + public_key).digest(network.max_prefixlen//8)
mask = int.from_bytes(network.hostmask.packed, byteorder='big')
host = int.from_bytes(hash, byteorder='big')
addr = network[host & mask]

The use of secret is optional but allows one to mix the addresses based on a shared secret. Substituting the link local range for the ORCHIDv2 range above should produce results similar to what you're getting. One thing to note, it's worth checking to see if the algorithm generates the network or broadcast addresses and either failing or shifting. (I'm considering adding a +1 or -1 based on whether we hit said address to the above; the real code just asserts right now.)

~Derrick

[1] https://github.com/pallas/wgnlpy/commit/5c1f4bf876b39bad29135370e5f297e305dab840


On 6/28/20 3:15 AM, Arti Zirk wrote:

On L, 2020-06-27 at 17:43 -0400, Reid Rankin wrote:
Luckily, Blake2s is a simple and elegant algorithm, and in an effort
to get some working code out there I've [implemented][1] it in ~100
lines of Bash script.
It turns out that Python includes blake2s implementation that seems to
work with default arguments. So it's possible to implement this IPv6
address calculation algorithm in 7 lines.

https://gist.github.com/artizirk/c91e4f8c237dec07e3ad1b286f1855a7

Reply via email to