# Validating Cotter's Identity Token

Cotter's token includes the user's email or phone number, your `API_KEY_ID`, and a `signature` . Here's the full `token` object:

```javascript
"token": {
    "identifier_id": "e8a47aff-f520-4b8d-952b-79d36d10fb3e",
    "expire_at": "1588849208",
    "identifier": "+12345678910", // user's email or phone
    "identifier_type": "PHONE",
    "receiver": "<YOUR API KEY ID>",
    "signature": "21P6mXSF2x357kZGkEMQTRTn3r...",
    "timestamp": "1586257208" // unix Timestamp
 }
```

{% hint style="info" %}
Check that the `receiver` contains your `API_KEY_ID`
{% endhint %}

#### Verifying the Signature

The signature ensures that this token comes from Cotter's server:

* Signature algorithm: `ed25519`
* Cotter's Public Key: `qqOaiQGjGsxBMgI5rdAasaACRiJthOqadmefjY5mS/c=`
* Signed Message:

```
{token.identifier}{token.identifier_type}{token.receiver}{token.expire_at}
```

{% hint style="info" %}
Note that there is no space and no `{}` in the message. It's all just 1 long string. ex. `+1234567890PHONEaaf7319d-8f91-4752-a23f-c43ba862d5481582679175`
{% endhint %}

#### Example

{% tabs %}
{% tab title="JavaScript" %}

```javascript

var cotter = require("cotter-token-js");

var cotterIdentity = new cotter.CotterIdentity(token);
var valid = cotterIdentity.validate()
```

{% endtab %}

{% tab title="React Native" %}

```javascript
import { Cotter } from 'react-native-cotter';

var valid = Cotter.validateIdentityResponse(response.token);
```

{% endtab %}

{% tab title="Go" %}

```go
// https://golang.org/pkg/crypto/ed25519/
func Verify(publicKey string, signStr string, args ...string) (bool, error) {
    str := []byte(strings.Join(args, ""))
    fmt.Println(strings.Join(args, ""))
    pubKey, err := base64.StdEncoding.DecodeString(publicKey)
    if err != nil {
        return false, responses.NewError("Fail verifying signature decoding pubkey", err)
    }
    signature, err := base64.StdEncoding.DecodeString(signStr)
    if err != nil {
        return false, responses.NewError("Fail verifying signature decoding signature", err)
    }
    valid := ed25519.Verify(pubKey, str, signature)
    return valid, nil
}

// Usage
valid, err := Verify(enum.CotterPublicKey, token.Signature, token.Identifier, string(token.IdentifierType), token.ReceiverID.String(), token.ExpireAt)

```

{% endtab %}

{% tab title="Python" %}

```python
# https://pynacl.readthedocs.io/en/stable/signing/
import binascii
import nacl.signing
import nacl.encoding

pub64 = "qqOaiQGjGsxBMgI5rdAasaACRiJthOqadmefjY5mS/c="
signatureB64 = token["signature"]
message = token["identifier"] + token["identifier_type"] + token["receiver"] + token["expire_at"]

signb = binascii.a2b_base64(signatureB64)
msgb = str.encode(message)

verify_key = nacl.signing.VerifyKey(pub64, encoder=nacl.encoding.Base64Encoder)
verify_key.verify(msgb, signb)
```

{% endtab %}
{% endtabs %}

Libraries for `ed25519` algorithm are available in [Javascript](https://tweetnacl.js.org/#/), [Golang](https://golang.org/pkg/crypto/ed25519/), [Python](https://pynacl.readthedocs.io/en/stable/signing/) and other languages.
