---
# System prepended metadata

title: 'Kiwi News Improvement Proposal #1 - Cryptographically crediting link submissions'

---

# Kiwi News Improvement Proposal #1 - Cryptographically crediting link submissions

Author: Tim Daubenschütz
Date: 2023-10-16
Have comments? => [attestate/kiwistand#106](https://github.com/attestate/kiwistand/issues/106)

## Motivation

Today, a Kiwi News link submission is the same as an upvote. Both are represented as the following JSON structure:

```json
{
    title: string,
    href: string,
    type: "amplify",
    timestamp: uint256
}
```

The system classifies one such message as a submission if it is the first mention of that link in `href`, and as an upvote if it is any following mention of that link.

The protocol isn't aware of a difference between upvote and submission. But this has been a mapping since implemented by all Kiwi News clients.

There now, however, arises an issue where a user can manipulate the timestamp of a message, hence, becoming credited by the current Kiwi News frontend as the original submitter of link.

This attack vector to steal a user's submission attribution comes from the fact that upvotes aren't content-addressing the submission directly and that all messages within the Kiwi News Protocol have a user-definable timestamp property.

To harden the protocol, we must therefore come up with an attribution-safe method of crediting original link submitters that isn't open for timestamp manipulation.

## Proposal

We propose a new type of upvote that allows crediting a specific original link submitter by creating an upvote message that specifically points at the submission object, and not at the to-be-upvoted hyperlink of the original submitter. The schematic below visualizes the difference between the current upvoting structure (called "version 1") and the proposal ("version 2").

![](https://hackmd.io/_uploads/BJgslFOZp.jpg)

We do not propose any major changes to the data model. However, we propose that a message's `href` must now also allow to point at an internal link-submission message with a lower timestamp. A pseudo code of this new validation logic follows

```
database {
    // gets a value using a key
    fun get(key) {} returns message or null
    
    // stores a value in the db
    fun store(value) {} returns key

    // ensures someone can only upvote a submission once. Must ensure submission.address != upvote.address
    fun isLegitUpvote(message) {} returns bool

    // ensures that a message is a submission
    fun isSubmission(id) {} returns bool
}

// essentially like ecrecover, however, this function will resolve a signer if it happens to be a delegate. The returned `signer` is always the message's signer. But `identity` is always the address that minted the NFT.
fun recoverSignature(signature) {} 
    returns { signer, identity } or throws

// the current message validation logic
fun validateVersion1(message) {} throws or returns null

// check if an address is allowed to interact
fun isMinterOrDelegate(address) {} returns bool

fun validate(message) {
    if (message.href.startsWith("https://")) {
        validateVersion1(message)
    } else {
        if (message.type != "amplify")
            throw Error("Invalid type value")
        
        submission = database.get(message.href)
        if (!submission)
            throw Error("Upvoted submission doesn't exist")
        if (submission.timestamp > message.timestamp)
            throw Error("Submission must be older than upvote")
        if (message.timestamp.isBefore("2023-01-01"))
            throw Error("Must not be older than 2023")
        
        if (!database.isSubmission(message.href))
            throw Error("Cannot upvote an upvote")
        
        { signer, identity } = recoverSignature(message)
        if (!isMinterOrDelegate(signer))
            throw Error("Only minters can upvote")
        
        if (!database.isLegitUpvote(message))
            throw Error("Already upvoted")
            
        if (submission.identity == identity)
            throw Error("Cannot self-upvote")
        
        database.store(message)
    }
}
```

Four validations are fundamentally new here:

1. An upvote's `href` value is looked up for its respective submission value in the database. If it doesn't exist, we consider the upvote invalid.
2. An upvote's timestamp must be older than that of the submission.
3. An upvote's `href` must not point to another upvote.
4. A submission's identity must not be that of an upvote's as this would mean someone can upvote their own submissions.

## Rationale

In its current implementation, Kiwi News Protocol doesn't properly cryptographically credit the submitter of a link as an imposter can spoof the user-defined timestamps in messages. 

Spoofing user-defined timestamps will continue to remain a problem in some uses cases of Kiwi News. We can, for example, imagine a front-running bot that constantly submits the latest links of others.

Still, by making upvotes point directly at the content digest of a submission, we are ensuring that, going forward, upvotes are permanently credited to a submitter.

## Drawbacks and Limitations

### Increasing protocol complexity

Kiwi News Protocol did have a weak pre-conceived notion of upvoting and submitting links beforehand. E.g. a user could only submit one normalized URI ever. However, by now making upvotes explicitly part of the message data model, by looking at the validation logic in the "Rationale" section, it is becoming clear that the complexity has increased. We are inspired about designing Kiwi News Protocol as a "[narrow waist](https://www.oilshell.org/blog/2022/02/diagrams.html)," however, it seems by giving  up this property we are able to significantly cryptographically hardening the upvote's attribution.

### Unclear usefulness

At the point of writing this document, it isn't entirely clear what the usefulness of this protocol hardening achieves. We know that cryptographic-hardness can be beneficial in the future when wanting to redeem karma scores onchain. However, there are many more protocol-hardening improvements necessary first before this can be considered.

Until then, however, the proposal can prevent a user from taking credit of all submissions.

## Considerations

### Deprecation period of old upvoting message

It may make sense to give a tolerant deprecation period during which it is possible to still submit old-style upvotes until all Kiwi News clients have implemented the new upvoting data structure. We think that the new upvoting structure can go live any time and that, from that moment on, e.g. a 1-2 month deprecation period can be set.

### Dealing with old karma

As only the main client ("Kiwi News") implements karma and attribution for addresses, it is out of scope of this document how they should deal with the old, non-cryptographically hardened karma.

## Copyright

Copyright and related rights waived via CC0.