I'll throw a bit more flavour in with the sibling comment talking about transposing x and y.
The system I work on every day has:
- multiple GPS receivers that report latitude, longitude, altitude (MSL) and altitude (HAE)
- an interface to some GeoJSON data where coordinates are stored as longitude, latitude
- a geographically-local Cartesian coordinate frame that is an AEP (Azimuthal Equidistance Projection) with a latitude/longitude origin. The "XYZ" axes of this frame are a NED frame (north, east, down)
- an aircraft-local Cartesian frame with FRD (forward, right, down) axes
- an interface that provides map tiles with zoom/x/y coordinates
- a bunch of other sensors mounted on the aircraft that have their own FRD frames, except the camera which has an RDF (right, down, forward) frame because... reasons.
- terrain RADAR units mounted on the aircraft at specific FRD locations that provide AGL (above ground level) measurements independent of their rotation (the aircraft can be 20 degrees nose-up and we still get a measurement straight down to the ground)
- terrain LIDAR units mounted on the aircraft at specific FRD locations and orientations that provide a straight-line measurement to the ground - if we're over flat ground and the aircraft is 20 degrees nose-up, these report AGL/cos(20 deg)
Keeping track of what frame everything is in is... a daunting task and we've definitely had bugs due to accidentally using a coordinate from the wrong frame. I've been deep into a bunch of this code this week and have been strongly considering doing a zero-cost abstraction similar to what Sguaba is doing, but for C++. I'm pretty sure that we could do it using templates and type tags without really changing any of the underlying math and without implementing a bunch of custom operators but I'm not 100% convinced of that yet.
Another related issue that I don't think is addressed by Sguaba is time. We're hopefully going to get everything standardized to PTP timestamps everywhere but currently all of these sensors are running on unsynchronized clocks and we also have to be careful about keeping track of the origin of a given timestamp and making sure to convert it into the right scale before using it.
The technique described keeps you, as a programmer, from transposing coordinate variables by type system enforcement. You might have variables x1, y1, x2, y2. If y1 and y2 have a different type than x1 and x2, it's much harder to transpose them. Large flying vehicles often have many coordinate systems. Enforcing types will keep you from using stage 1 variables in a stage 2 context without type conversion.
I left the aerospace industry in 1992. Before that, I did some work with a program called "BOSOR5" - "Buckling of Shells of Revolution" (https://shellbuckling.com/BOSOR5.php). The X,Y coordinates appears as Y,X in the output. Very confusing, lots of problems because everyone habitually reads X first, then Y, left-to-right.
Imagine how much trouble it was to work on a Saturn 5: https://oikofuge.com/coordinate-axes-apollo-saturn-1/ If you have a type system with different types for all the axes, you will incur far fewer programming-domain errors.
So the reason _why_ we want the code to be explicit is that we want to be explicit always of the coordinate system we are in. Otherwise _extremely_ hard to find bugs can and will creep in - a float is a float.
The stuff I worked on input coordinates were left handed but the output coordinates were right handed.
That's not what is happening here. With this software there are no raw floats; all variables are typed by the kind of coordinate system (WGS84, ECEF, etc.)
Using your example, the variables would be typed by left- or right-handed. So it is impossible to mix them up, e.g., perform some illegal operation combining them.
Whether implicit conversion is allowed is just saying, does the programmer have to call a function to convert type A -> B, or can the compiler do that for them?
For example,
void doFoo(LeftHandedVec3 v);
RightHandedVec3 myData;
// With explicit conversion.
doFoo(convertToLeftHanded(myData));
// With implicit conversion.
doFoo(myData);
This is a fantastic example of applying deception strategies in practice as part of a detection & response plan. The most common use case is as a canary, but it absolutely works as evidence of compromise, too.
I won't comment on the specifics of the case (the complaint comes across as very convincing), but I will remind people that it's common for investigations to ostensibly show an employee doing bad things, when in reality it's e.g. that employee's credentials/devices that are compromised.
Re: hashing: Yes, but I'll leave that one to Paul who is a lot smarter than I am :)
Re: QA: can you say a bit more about the type of coverage you're worried about? Is your concern that we'd be missing APIs, or that the storage format itself breaks, resulting in fact elision? payne (the underlying project) has a borderline obnoxious amount of tests, but that doesn't mean we didn't miss anything :)
FYI: we're planning a followup post for people who are less interested in the Datomic mechanics and more interested in the usefulness to investigations and other security functions. Informally, I think of it this way: your SIEM has the deltas, but often you want the contextual states in between the deltas (and a lot of investigation is about trying to reason about that state). We built this tool originally to support that, and it turned out that approach was also super useful for things like compliance, CSPM...
(I'm one of the founders of Latacora and reviewed the post.) If any of you are at Heart of Clojure, I'll be there both wearing my Latacora hat and my Clojurists Together hat :)
I don't know if I count as a "feline friend", but: SIDH kept the DH shape. Being able to upgrade the protocols we had relatively closely is appealing. "Structure is useful but seems precarious" wasn't exactly secret knowledge.
We did an updated version of the Cryptographic Right Answers for PQC. Given how quick the field is moving, I'm sure we're going to have to edit it a bunch :)
(I don't disagree! I'm just saying: you haven't advanced your argument or answered GP's question.)
reply