Caralynx
banner
sudo.caralynx.com
Caralynx
@sudo.caralynx.com
210 followers 70 following 550 posts
Reverse engineering, Japanese toy hacking, constantly distracted. Is ordinarily a tufty cat. Icon by @rokuromon.bsky.social, banner by @hackmonthegoat.bsky.social‬ Teardowns: @teardowns.caralynx.com | Ko-fi: https://ko-fi.com/caralynx
Posts Media Videos Starter Packs
Pinned
Hello! I'm cyanic, and I mess around with Japanese toys. This account will mostly be for personal interests. I'll also repost the start of teardown threads here, but if you want to follow the full thread, check @teardowns.caralynx.com.

🎨: @artmab.bsky.social
Read through the repo, you tell me what you think is missing. It's the research folder one. There's some things that have not been fully discovered with regards to content, but there should be sufficient information for doing things with the prongs.
You don't need a microcontroller, just a UART adapter.
It's unknown how unique the device key is. Currently it's the same at least across a manufacturing batch. The P-Com is a microcontroller that wraps the protocol, but is frankly not worth considering due to its proprietary and needlessly complex implementation.
It's in the encrypted part of the firmware. I made a decrypter, which requires the device key, which you can extract with the microcontroller's UART console or SWD (which is disabled in the firmware but enabled when there is no valid firmware).
There's a description of the hardware connection as well.
It's all in or referenced by the repo. You've got the base transport protocol and a reference implementation (but you'll have to find your own transfer secret), a description of the playdate flow, and a description of the gifting flow. Downloads are just bulk files and have no special flow.
All you need is a UART adapter and some software to play the part, so yes, an ESP32 should work. Any microcontroller with a UART peripheral should work as long as you have software to run the protocol.
*keeps the antlers for my collection*
I'd like to get one, though can't right now. Will this be available again some time in the future?
I more or less repacked one of the DLCs with a new sprite and some string edits. Not quite ready for prime time, I want to know how the animations work first.
Here's the code for generating that hash. Way too much SHA256 and SHA512 IMO, they could probably have made this simpler. Or used an HMAC.
Bonus: parameter hashing on the API. When you're calling the API, it expects a hash under the `x-bambi-hash` header that hashes the parameters passed to the endpoint. This is probably to make sure only authorized clients can call the API, but is kind of weak.
And that's pretty much it. The core of it is an xorshift32 RNG with a fixed seed generating a sequence of tiles to draw.
The generate scramble map function takes an array, and then using xorshift32 assigns a number to each element. It then sorts the array by that generated number and returns the sorted array.

The xorshift32 function is also a generator. It puts the seed into a Uint32Array to ensure range.
Finally, we get into the actual scrambling logic. First is a generator function that returns the X/Y coordinate (in terms of tiles, not pixels) of the tiles to swap. It passes the array [0, 1, ..., numTiles ** 2] to the generate scramble map function, and generates which tile to copy in dest order.
The scrambled width and height is capped to that, then it calculates the size of each tile. Because of the requirement that the tile size is a multiple of 8, that means for images that do not have dimensions that are a multiple of 8, a strip on the right and/or bottom side will not be scrambled.
The tile size is calculated by first finding the LCM of the number of tiles horizontally and vertically (defined as 4 by the caller) and 8. Not sure why it needs to be a multiple of 8, but that's what they specified.
The scramble seed is valid if it's not undefined and is a 32-bit unsigned number that's at least 1.
Let's look at the unscramble function. It draws the scrambled image, gets the tile size and checks whether it and the scramble seed (supplied by the web API) is valid, clears the scrambled region (we'll see why it draws the image first later), then draws each tile according to a generator.
Not sure why they specifically scale it down when it's smaller. Maybe to save on memory?
Basically it draws the scrambled image into an offscreen canvas (if available), unscrambles it, then copies the unscrambled image into the unscrambled canvas. There's an interesting rescaling that happens if the target width for the canvas is less than half the size of the original image.
The page sets up a Vue component for displaying a canvas of the unscrambled image. That then creates a class that generates said canvas, and exposes functions for loading the scrambled image and drawing to the unscrambled canvas. Here's the code for drawing the canvas.
I spent some time figuring out Ciao Plus' image scrambling algorithm because I wanted to archive the Tamagotchi Manga on it. Let's take a look.
Reposted by Caralynx
Sprites! The first three monthly brush tests were of Sudo, Banon, and Noko. :D

@sudo.caralynx.com @ucbronzewing.bsky.social
#furryart #furry #commission
There's more info at github.com/GMMan/tama-p.... The readme of the tamacom library gives an example of how to send and receive packets.
github.com