# 3.2 Public vs Private

In this chapter we'll go through the core concepts that separate Leo from languages used on other blockchains.

Remember, Leo is a language that was made to write programs, where users are able prove that some function returns some outputs on given inputs. The prover always knows what those inputs and outputs are. On the contrary, when writing the program you can chose what inputs and outputs the verifier will be able to know.

**To specify which inputs/outputs will be visible by the verifier, you use the private or public keywords.**

Here's a first example. Let's say a user wants to prove he knows a values which has a specific hash. He could use a program with the following code:

```rust
program public_private.aleo {
    transition hash(private a: u128) -> (public u128) {
        let hashed: u128 = BHP256::hash_to_u128(a); 
        // 'BHP256::hash_to_u128' is simply some hash function
        return hashed;
    }
}
```

And then execute the following command to generate the proof on input `123u128`:

```bash
leo execute hash 123u128
```

The execution JSON output gives (truncated, for clarity):

```json
...
  "program": "public_private.aleo",
  "function": "hash",
  "inputs": [
    {
      "type": "private",
      "id": "1962240563724633819199836007983492948966298136554977151826721901937221388753field",
      "value": "ciphertext1qyq2524n4k73nz6ws6qf3xn6d9ud2a02aja4x0qmp85jnk57cxvq6rs2mqut3"
    }
  ],
  "outputs": [
    {
      "type": "public",
      "id": "6397735181602383364235662871012389317153917860343012180688468769946408542910field",
      "value": "26515625101883903322553063858644017311u128"
    }
  ],
...
```

As you can see here the type of the only input is private, and the value is a ciphertext, which can be decrypted using the prover view key to recover the input value itelf.  On the contrary the output is a public value: `26515625101883903322553063858644017311u128` which corresponds directly to the hash of `123u128`.

Transitions can have up to 16 inputs and outputs, which can all independently be tagged as public or private.

{% hint style="info" %}
By default, if you don't specify any visibility for an input/output, it will be private.
{% endhint %}

The address of the prover itself is private as well, and accessible in a program using the `self.signer` keyword. For example the following code could be used to prove that the prover's address is one of the three hardcoded addresses:

```rust
program public_private.aleo {
    transition includes_signer() -> (public bool) {
        let included: bool = (
            self.signer == aleo1845psejz2fqy3zwjvdxjrexs9fwdh2tqjwlhtdjs2t6thr07ccyq3fvmfd
            || self.signer == aleo1hqrz7wukfv2mmxzuzwes0w44s2se2v98w840k6euncdm8mwfd5pq2dwjcy
            || self.signer == aleo15eapl52ju8a6zxz5qnau7nlvadz3x3napa0qds7c04d8qkt6f5gs747czs
        );
        return included;
    }
}
```

The execution of this function, along with its proof, reveals nothing about the prover address other than if it's included or not in the list of three addresses.

We're still missing a last important piece of input/output visibility that's available on Aleo. But before looking into it, we need to describe first all the types available in the language.
