Since all objects receive new keys, are sent from one avatar to the other there may be a need to track down an object. As a practical application, suppose you have an object with transfer permissions that you wish to send off to other avatars. However, after it has been passed to several avatars, you want to determine who the original owner of the object was.
This works fine if the original owner is also the creator because one can use llGetCreator()
for that. However, if the object's original owner is supposed to be a different avatar other than the creator, it becomes very difficult to track who the original owner was after several passes.
Furthermore, under the assumption that the object may be copied using rogue clients, it becomes almost impossible to track down whether the object is original or not.
The authenticity check satisfies the following properties:
integer checkOriginal(key id) { // Check if we have the original number of primitives. if(llGetNumberOfPrims() != 15) return FALSE; // Check if the creator of the object is Morgan LeFay. if(llGetCreator() != "1ad33407-a792-476d-a5e3-06007c0802bf") return FALSE; // Check the sizes and positions of all primitives. list size = [ <.032813, .015186, .022779>,<.018223, .015186, .015186>,<.015186, .075929, .015186>,<.018223, .015186, .015186>,<.015186, .015186, .015186>,<.016704, .076547, .046667>,<.046755, .010000, .010000>,<.018223, .030371, .030371>,<.020000, .013000, .010000>,<.010000, .010000, .046230>,<.030000, .030000, .030000>,<.030000, .030000, .030000>,<.010000, .014000, .010000>,<.012000, .016000, .010000>,<.016840, .076546, .073333> ]; integer itra = 14; do { if((string)llList2Vector(llGetLinkPrimitiveParams(14-itra+1, [PRIM_SIZE]),0) != (string)llList2Vector(size, itra)) return FALSE; i += llList2Vector(llGetLinkPrimitiveParams(14-itra+1, [PRIM_SIZE]),0); } while(--itra>0); return llAbs((integer)((integer)(i.x*((integer)("0x"+llGetSubString((string)id,-8,-1)))) & (integer)(i.y*((integer)("0x"+llGetSubString((string)llGetCreator(),-8,-1)))) ^ (integer)(i.z*((integer)("0x"+llGetSubString("2358cb5c-578a-4b90-932f-54d01e36cfc8",-8,-1)))))); }
The procedure consists in creating a threeway hash of several geometric parameters of the lighter. This works under the assumption that any copying or tampering with the object will void the authenticity check. In some ways it creates a signature that is stored in the no-modify object which is checked on request.
The procedure is the following:
Morgan LeFay
. Any copying attempts will be voided at this point since the creator of a copied object will not have the same avatar UUID as Morgan LeFay
.x
-component of the resulting size vector and hash it with the name of the owning avatar.y
-component of the resulting size vector and hash it with the creator of the object.z
-component of the resulting size vector and hash it with a secret.The result is that when an identity check is requested, the hash can be rebuilt using the parameters and then checked with the stored hash. If the hashes match, then the object is considered to be original.
SecondLife suffers from some bit-rot at the level of geometries. Apparently objects may seem to change their dispositions slightly. The procedure above avoids that problem by preferring to build a hash based on the sizes of individual primitives rather than their relative positions.