KIP core concept Sum
Checksum information is part of the lower-level API that KIP itself uses.
The Sum
class collects checksum information, and can be updated
with new data at any time. It offers a few advanced facilities,
such as forking or cloning the hash and marking syntactical spots
of interest that should not cause security problems as a result
of invisible binary boundaries.
The need for a separate checksum is not just because of the more
powerful functionality than the MAC included in kip_up()
, but
there are strong security reasons, such as the number of bits
involved, the data spanned and the longevity of the data. Try
to think of the MAC as a short-lived, message-specific protection
against accidental changes, whereas a Sum
protects against
deliberate assaults on your security. And yes, it takes some
determination to mount an attack on a MAC and if you test it a
few times by hand you should see you bit changes or byte removals
trigger alerts quite consistently; but if you really wanted to
put in the effort and compute power you would probably find a
way to trick the MAC. Not so with the Sum
. So when you need
to protect anything but messages in transit as KIP does for its
internal purposes, use a Sum
. Really, don't be shy and just
always use a Sum
.
Every internal Key
has a Sum
attached to it.
Not all Sum
instances are also Key
instances, though.
Interface.
A few useful calls for the Sum
class:
-
Sum(context,keyid)
creates a newSum
object, to manage the checksum with the support of the identified key. Note that everyKey
already has aSum
builtin by being a subclass hereof. Note that "keyid" is actually a sum-or-key-id, which is a larger set of values than just key-id. -
sumid()
returns the identity for thisSum
. Note that the set of all sum identities includes the set of all key identities, because everyKey
has aSum
built in. This is a superset, the reverse need not be true. It is true however that everySum
connects to oneKey
. -
append(bytes)
appends data bytes to thisSum
object or, if this object happens to also be aKey
, insert it between data that passes throughkip_up()
andkip_down()
calls. -
restart()
theSum
object in a state that has not seen any data passing in yet. This works forKey
objects too, and then forgets allkip_up()
andkip_down()
data too. -
fork()
the Sum in its current state, and allow the old and new to continue in different or same directions without any further relation; do however share the history up to the moment of thisfork()
call. The forkedSum
will be tied to the sameKey
, but it will not be updated by itskip_up()
andkip_down()
operations, while that aspect of the originalSum
continues to exist or not, as before. -
mark(typing=None)
inserts a separation marker into the hash flow. This is a new idea. It allows clear separation between bits that must never been seen to connect, and follows the basic philosophy that hash input is secure if it could be parsed back. In this case, markers are inserted in the input flow, as well as an extra one at the end, in a reproducable manner that requires no escaping and no special characters. To yield the best possible result, you could add a textual hint about the marker point, such as a syntactical choice made on account of prior and/or following data. Providing no typing differs from providing any string value, even an empty string. You are welcome to use international type; we will map it in a repeatable manner to a sequence of bytes. Note that it is text, so there are no intermediate 0x00 bytes. This imposes no restrictions on the other bytes, though. -
merge(*addends)
other sums' current/intermediate hash values into this one and then continue. This allows the merging of data flows. The addends are processed in the order in which they appear as arguments. -
sign()
produces signature mud for the currentSum
state, where the boundKey
is used to produce the signature. Note that everySum
has an associatedKey
, not just the ones that happen to play the role ofKey
through subclassing. Operations likesum_start()
andfork()
always share theKey
ID into the newly createdSum
object. -
verify()
checks signature mud bytes against the currentSum
state, and use the bound Key to verify the signature. To make this work, the sameKey
ID must have been associated with thisSum
as was shared before the verifiedsign()
call; that is the responsibility for the application programmer.