Háskólinn í Reykjavík, Haustönn 2016 |
Reykjavik University, Fall 2016 |
key_gen() to generate a key of whichever type is
appropriate for the cryptosystem you are using
<string> encrypt(<string>
cleartext, <key-object> key) which outputs
the ciphertext for a given cleartext and key
<string> decrypt(<string>
ciphertext, <key-object> key) which
outputs the cleartext for a given ciphertext and key
<string> sign(<string>
message, <key-object> key) which outputs
the signature with respect to the given [private] key on the
given message
<bool> verify(<string>
message, <string> signature,
<string> key) which tells if the given
signature is valid for the given key on the given message
<128-long bit string>
<void> work(<128-long bit string>
prefix, <int> len) which returns a bit
string which when appended to the given prefix and used
as input to SHA256 produces an output whose last len bits
are all 0.
bool new_client(public_key key)key. Returns false if there
already exists a client with that ID,
otherwise true.
transactionID authorize(int n, int m,
ID in1, int x1, ..., ID inn, int xn,
ID out1, int y1, ..., ID outm, int ym,
sig s1, ..., sig sn)
which checks if the multi-input and -output transaction is
valid, and, if so, performs the corresponding deductions from
input accounts and deposits to output accounts, and returns a
new, unique transactionID, otherwise returns
null.
A proposed transaction is valid if
in1, ..., inn, out1, ..., outm are recognized client IDs,
x1+...+xn = y1+...+ym (so total input of BB\$s equals total output),
j in the range
1≤j≤n, sj
is a valid signature on the concatenation of the byte
representations of n, m, in1, x1, ..., inn, xn, out1, y1, ..., outm, ym
j in the range
1≤j≤n, xj is
no more than the amount the BBB has in the account for
inj.
bool verify(ID out, int x, transactionID t)
which returns true if the transaction with the
given transactionID resulted in a payment of
BB\$x to the client ID out.
C to another
entity E should be encrypted with E's
public key, signed with C's private key, and then
have C's ID prepended to the message before it is
transmitted. All message recipients should check the signatures
on their messages and flag an error if it does not verify.
audit.
authorize method, in the
same order. Preceding that information, should be a hash
pointer, being the hash of the entire previous block
(including its hash pointer, in turn).
audit method needs to traverse the entire
block chain, making sure that every transaction makes sense
and is valid, and that all coins come from that original supply
created in the genesis block.
Let's call this next version of our toy electronic economy Block Chain Bucks [BCB with currency denoted BC\$]. It will have a central server, the Block Chain Bank [BCB] which maintains the transaction block chain, manages insertions to that chain, and responds to queries about the success of transactions which are on the chain.
BCB should maintain a valid block chain which has one transaction per block. The validity conditions are as follows:
int field, specifying the number
n of participants in the transaction.
ID1, ..., IDn
of the IDs, of clients involved in this transaction.
start1, ..., startn,
end1, ..., endn, of
ints, being the input and output BC\$ values
owned by each ID involved in the transaction, meaning that
each IDj owned
startj BC\$ just before the
transaction and owns endj BC\$ just
after the transaction.start1 +
... + startn = end1 + ... +
endn and that none of
the values of the startj or
endj are negative.j,
endj≠startj, although
that is not actually required. [Having
an IDj which did not change
values of BC\$s, so
endj = startj,
would mean that the actor IDj
approved of the transaction, even if she didn't have
a direct financial stake it it — maybe this was
the guardian of a minor involved in a transaction, who
needed to sign off on the transaction, for
example.]
s1, ..., sn
of signatures, where sj is the
signature under IDj's private key
of the concatenation of the bytes for n,
ID1, ..., IDn,
(end1-start1), ...,
(endn-startn).
startj
corresponding to an identity IDj, the
ending value endk in the most recent
transaction before $T$ where for some k, the
identity IDk in that past transaction
was the same as IDj in $T$, satisfies
endk=startj.
[Meaning that the number of BB\$ doesn't
change between successive valid blocks in which it is a
transaction participant.] If there is
no previous such transaction in which the identity
IDj appears, then this
startj must be 0.
[Meaning that new identities start with
BC\$0.]
Note that, as we have designed the transaction block chain here,
the current number of BB\$ owned by some actor is the value of
endj for the most recent transaction on the
block chain for which that actor's ID is one of the ones in the
transaction, say it is IDj.
BCB will still have a central bank, which we will call the Block Chain Bank [BCBa]. When it starts, it will make a founder's ID and create the genesis block. After that, it will handle the following requests:
bool new_client(public_key key)false if there already exists an actor
with that ID, otherwise true.
hashval authorize(int n,
hashval ID1, ..., hashval IDn,
int Δ1, ..., int Δn,
sig s1, ..., sig sn)
which checks if the multi-input and -output transaction is
valid, and, if so, returns the hash of the corresponding block
chain transaction block; otherwise returns null.
A new block chain block is created as follows:
n of the
authorize call.
j in the range from
1 to r, do the following:
IDj as an
involved ID, say it was block $B$.
startj=0.
end value for
IDj in that block $B$ as the
value of startj.
endj=startj+Δj.
start1, ..., startn,
end1, ..., endn, sig1,
..., sign to the new block.
authorize with value
false, otherwise accept this block as the new
end of the block chain and return with value true.
bool verify(ID out, int x, transactionID t)
which returns true if the transaction with the
given transactionID resulted in a payment of
BB\$x to the client ID out.
new_client(public_key key) which established a new
ID. It could also take a call of the form
get_public_key(hashval ID) which takes an ID as input
and returns the associated public key. This seems to put more
power in the hands of the bank, which is what we are trying to move
away from, but really BCBa is coming to play more or less the
role only of the network (handling communications, consensus,
etc.)
bool new_client(public_key key) registers a new
identity with the BC network, returns either the corresponding
ID (which is a hashval) or null if
this public key has already been registered.
public_key get_public_key(hashval ID) returns
the public key of a registered client with the given ID, or
null if that ID is not recognized.
hasval get_current_chain_tail_pointer() returns
the hash pointer of the current tail of the block chain.
block_data get_block(hashval pointer) returns
the contents of the block with the given hash pointer, or
null if the pointer is not recognized.
bool put_block(block_data block) sees if the
given block would make a valid block chain if it were
appended to the block chain (checking the conditions described
above in yesterday's discussion and that
the hash pointer in this new block points to the current
last block on the block chain) and, if so, adding it there.
new_client call. Then, when acting as a payer, they
will
put_block with this new
proposed block. If it fails, repeat the construction and
put_block until it succeeds. Upon success, a
hash pointer to this block can be sent to the payee in the
role of a transaction ID.
get_current_chain_tail_pointer() and see
if it is equal to that client's view of its current chain tail.
get_block, starting with
that newer BCBa version of the block chain tail pointer and
ending when the newly acquired block's hash pointer to the
previous block is pointing to the client's pre-update version
of the hash pointer to the current block chain tail.
Proof-of-work is essentially one-CPU-one-vote.This has been a value of the cryptocurrency community since the beginning, akin to the centrality of idea of decentralization (if you will forgive the pun) authority, rejecting TTPs. The fear is, however, that big players will be able to make the large up-front investment necessary to create and install large quantities of application-specific integrated circuits [ASICs] — special chips which can run through potential nonces for the SHA-based proof-of-work faster than anyone else can on a general-purpose CPU or even GPU adapted for mining.
scrypt algorithm is an example. For this, a
parameter N is chosen. Initialization is done as
V = buffer of size N
V[0] = <seed>
for i=1 to N-1
V[i] = sha256(V[i-1])
Then, on input X, do the following
for i=1 to N
j = X mod N
X = sha256(X ⊕ V[j])
The output is again in X.
Well, look at a term like $$ \prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x) $$ This is a polynomial of degree $k-1$ whose value when $x$ equals any of the $x_\ell$ is zero except for the case of $x=x_j$, when it is non-zero (remember the $x_1,\dots,x_k$ are all distinct).
We can make that non-zero value at $x=x_j$ be $y_j$ by multiplying by the correct constant, as $$ \left[\frac{y_j}{\prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x_j)}\right]\prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x) $$ (the term in the square brackets here is a constant, while the other term is a polynomial of degree $k-1$).
So this one expression is a polynomial of degree $k-1$ with value 0 at all of the $x_\ell$ except for $x_j$, where it's value is $y_j$. If we then add these up for all values of $j$ from $1$ to $k$, since all of them are 0 at each $x_j$ except for one which has the value $y_j$, we will have a polynomial with the behavior we were looking for, $$ \sum_{j=1}^k\left(\left[\frac{y_j}{\prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x_j)}\right]\prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x)\right) = \sum_{j=1}^k\left(\frac{y_j \prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x)}{\prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x_j)}\right) , $$
and of course there is a unique polynomial with those desired properties, so this one must be it!
Note if we are interested in the constant coefficient $a_0$ of this polynomial, we can find it just by plugging in $x=0$ to that formula, giving $$ a_0 = \sum_{j=1}^k\left(\frac{y_j \prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-0)}{\prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x_j)}\right) = \sum_{j=1}^k\left(\frac{y_j \prod\limits_{\ell=1\\\ell\neq j}^{k}x_\ell}{\prod\limits_{\ell=1\\\ell\neq j}^{k}(x_\ell-x_j)}\right) . $$
This can be useful in the Shamir secret-sharing scheme, although to avoid precision issues with the divisions in the formula, we work in some $\ZZ^*_p$ where $p$ is a large prime. All elements such a $\ZZ^*_p$ have multiplicative inverses, so that everything can be represented by integer values and division can be done with perfect precision.
(p, S1, ..., Sn) = get_shares(k, n, S)
where inputs are natural numbers representing the $k$ and $n$ of
a $(k,n)$-secret sharing scheme and the secret $S$ itself, and
the output is a tuple representing general information needed
by all shares (here, $p$, for "parameter"), and the $n$ shares.
S = combine(k, n, p, S1, ..., Sk)
where the inputs are the values $k$ and $n$ of the
$(k,n)$-secret sharing, the $p$ parameters generated by
get_shares, and $k$ of the shares, while the
output is the recombined secret.
get_shares:
combine:
This is somewhat controversial in the Bitcoin community. Some people think it is a nice new use of the block chain. Others think that it will lead to horrible "block chain bloat."
Each student must do the following:
scrypt, something which searches for Cunninham
chains, or a secret sharing tool.
If you worked with other students on some or all of the coding projects, that is perfectly fine, and each group may send to your instructor only one copy of their code. Please, however, make sure that whoever sends the code also tells the names of everyone on the team.
All materials should be submitted no later than 23:59:59 (GMT) on 19 December 2016.