Download as pdf or txt
Download as pdf or txt
You are on page 1of 14

Table of contents

Title Page number


Linked list 1
Hashing 2-5
Blockchain 6
Classes 7-12
Problems solved 13
Linked List

In computer science, a linked list is a linear collection of data elements, in which


linear order is not given by their physical placement in memory. Instead, each
element points to the next. It is a data structure consisting of a group of nodes which
together represent a sequence. Under the simplest form, each node is composed of
data and a reference (in other words, a link) to the next node in the sequence. This
structure allows for efcient insertion or removal of elements from any position in the
sequence during iteration. More complex variants add additional links, allowing
efcient insertion or removal from arbitrary element references. A drawback of linked
lists is that access time is linear. Faster access, such as random access, is not
feasible. Arrays have better cache locality as compared to linked lists.

The way a blockchain is represented as a singly linked list. Each block has a hash of

the previous block which can be thought of as a pointer to previous block.

Some diferences are that in a linked list, there are generally more operations

for a linked list that are not available in a blockchain, most notably being able

to remove a block and to add a block in the middle of the list/chain.


Hashing

Hashing is an improvement over Direct Access Table. The idea is to use hash function
that converts a given phone number or any other key to a smaller number and uses
the small number as index in a table called hash table.

Hash Function: A function that converts a given big number to a small practical
integer value. The mapped integer value is used as an index in hash table. In simple
terms, a hash function maps a big number or string to a small integer that can be
used as index in hash table.

A good hash function should have following properties


1) Efciently computable.
2) Should uniformly distribute the keys (Each table position equally likely for each
key)

Hash Table: An array that stores pointers to records corresponding to a given phone
number. An entry in hash table is NIL if no existing phone number has hash function
value equal to the index for the entry.

Collision Handling: Since a hash function gets us a small number for a big key,

there is possibility that two keys result in same value. The situation where a newly

inserted key maps to an already occupied slot in hash table is called collision and

must be handled using some collision handling technique. Following are the ways to

handle collisions:

•Chaining: The idea is to make each cell of hash table point to a linked list of

records that have same hash function value. Chaining is simple, but requires

additional memory outside the table.

•Open Addressing: In open addressing, all elements are stored in the hash

table itself. Each table entry contains either a record or NIL. When searching for

an element, we one by one examine table slots until the desired element is

found or it is clear that the element is not in the table.


SHA256

Cryptographic hash functions are mathematical operations run on digital data; by


comparing the computed "hash" (the output from execution of the algorithm) to a
known and expected hash value, a person can determine the data's integrity. For
example, computing the hash of a downloaded fle and comparing the result to a
previously published hash result can show whether the download has been modifed or
tampered with.A key aspect of cryptographic hash functions is their collision
resistance: nobody should be able to fnd two diferent input values that result in the
same hash output.

A hash is not ‘encryption’ – it cannot be decrypted back to the original text (it is a

‘one-way’ cryptographic function, and is a fxed size for any size of source text). This

makes it suitable when it is appropriate to compare ‘hashed’ versions of texts, as

opposed to decrypting the text to obtain the original version.

Such applications include hash tables, integrity verifcation, challenge handshake

authentication, digital signatures, etc.

•‘challenge handshake authentication’ (or ‘challenge hash authentication’) avoids

transmissing passwords in ‘clear’ – a client can send the hash of a password

over the internet for validation by a server without risk of the original password

being intercepted

•anti-tamper – link a hash of a message to the original, and the recipient can

re-hash the message and compare it to the supplied hash: if they match, the

message is unchanged; this can also be used to confrm no data-loss in

transmission

•digital signatures are rather more involved, but in essence, you can sign the

hash of a document by encrypting it with your private key, producing a digital

signature for the document. Anyone else can then check that you authenticated

the text by decrypting the signature with your public key to obtain the original

hash again, and comparing it with their hash of the text.

SHA256 is a hash function with a digest of length 256 bits, block size 512 bits and
word size 32 bits.
Pseudo code SHA256

Note 1: All variables are 32 bit unsigned integers and addition is


calculated modulo 2^32
Note 2: For each round, there is one round constant k[i] and one entry in
the message schedule array w[i], 0 ≤ i ≤ 63
Note 3: The compression function uses 8 working variables, a through h
Note 4: Big-endian convention is used when expressing the constants in this
pseudocode,
and when parsing message block data from bytes to words, for example,
the first word of the input message "abc" after padding is 0x61626380

Initialize hash values:


(first 32 bits of the fractional parts of the square roots of the first 8
primes 2..19):
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19

Initialize array of round constants:


(first 32 bits of the fractional parts of the cube roots of the first 64
primes 2..311):
k[0..63] :=
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa,
0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb,
0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624,
0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb,
0xbef9a3f7, 0xc67178f2

Pre-processing:
begin with the original message of length L bits
append a single '1' bit
append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K +
64 is a multiple of 512
append L as a 64-bit big-endian integer, making the total post-processed
length a multiple of 512 bits

Process the message in successive 512-bit chunks:


break message into 512-bit chunks
for each chunk
create a 64-entry message schedule array w[0..63] of 32-bit words
(The initial values in w[0..63] don't matter, so many implementations
zero them here)
copy chunk into first 16 words w[0..15] of the message schedule array

Extend the first 16 words into the remaining 48 words w[16..63] of the
message schedule array:
for i from 16 to 63
s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-
15] rightshift 3)
s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-
2] rightshift 10)
w[i] := w[i-16] + s0 + w[i-7] + s1

Initialize working variables to current hash value:


a := h0
b := h1
c := h2
d := h3
e := h4
f := h5
g := h6
h := h7

Compression function main loop:


for i from 0 to 63
S1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate
25)
ch := (e and f) xor ((not e) and g)
temp1 := h + S1 + ch + k[i] + w[i]
S0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate
22)
maj := (a and b) xor (a and c) xor (b and c)
temp2 := S0 + maj

h := g
g := f
f := e
e := d + temp1
d := c
c := b
b := a
a := temp1 + temp2

Add the compressed chunk to the current hash value:


h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
h4 := h4 + e
h5 := h5 + f
h6 := h6 + g
h7 := h7 + h

Produce the final hash value (big-endian):


digest := hash := h0 append h1 append h2 append h3 append h4 append h5
append h6 append h7
BlockChain

A blockchain is a continuously growing list of records, called blocks, which are linked
and secured using cryptography. Each block typically contains a cryptographic hash of
the previous block, a timestamp and transaction data. By design, a blockchain is
inherently resistant to modifcation of the data. It is "an open, distributed ledger that
can record transactions between two parties efciently and in a verifable and
permanent way". For use as a distributed ledger, a blockchain is typically managed by
a P2P network collectively adhering to a protocol for inter-node communication and
validating new blocks. Once recorded, the data in any given block cannot be altered
retroactively without the alteration of all subsequent blocks, which requires collusion of
the network majority.
Classes
public class Blockchain {
    Block start;
    Block last;
    public Blockchain(){
        last=start=new Block(0, "none", "0");
        start.next=null;
    }

    public Block getLatestBlock(){
        return last;
    }

    public void addBlock(String vote_for) throws 
ChainInvalidException{
        if(!isValid()) throw new ChainInvalidException();
        Block latestBlock=getLatestBlock();
        Block blk=new Block(latestBlock.index+1, vote_for, 
latestBlock.hash);
        latestBlock.next=blk;
        last=blk;
    }

    public boolean isValid(){
        Block prev=start;
        Block current=start.next;
        while(current !=null && current.next!=null){

            if(!current.prev_hash.equals(prev.hash)) {

                //System.out.println("point 1");
                return false;
            }
            current=current.next;
            prev=prev.next;
        }
        current=start;
        while(current!=null){
            if(!
current.calculateHash(current.index+current.vote_for+current.prev_
hash).equals(current.hash)) {
                //System.out.println("point 2");
                return false;
            }
            current=current.next;
        }
        return true;
    }
    public int[] getVotes() throws ChainInvalidException{
        if(!isValid()) throw new ChainInvalidException();
        Block ptr=start;
        int[] votes=new int[3];
        while(ptr!=null){
            if(ptr.vote_for.equals("1")) {
                votes[0]++;
                //System.out.println("1");
            }
            if(ptr.vote_for.equals("2")) {
                votes[1]++;
                //System.out.println("2");
            }
            if(ptr.vote_for.equals("3")) {
                votes[2]++;
                //System.out.println("2");
            }
            ptr=ptr.next;
        }
        //for(int v:votes) System.out.println(v);
        return votes;
    }
}
public class Block{
    String vote_for;
    int index;
    String hash;
    String prev_hash;
    Block next;

    public Block(int index, String vote_for, String prev_hash){
        this.vote_for=vote_for;
        this.index=index;
        this.prev_hash=prev_hash;
        this.hash=this.calculateHash(index + vote_for + 
prev_hash);
        this.next=null;
    }

    public String calculateHash(String data){
        MessageDigest digest = null;
        try {
            digest = MessageDigest.getInstance("SHA­256");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        byte[] hash = 
digest.digest(data.getBytes(StandardCharsets.UTF_8));
        return HexBin.encode(hash);
    }
}
public class SHA256 {
    final int w=32;

    final int[] K = {
            0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
            0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
            0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
            0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
            0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
            0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
            0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
            0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
    };

    private int modulo(int dividend, int divisor){
        if(dividend>=0) return dividend%divisor;
        return divisor + (dividend % divisor);
    }

    private int Ch(int x, int y, int z){
        return (x & y) ^ (~x & z);
    }

    private int Maj(int x, int y, int z){
        return (x & y) ^ (x & z) ^ ( y & z);
    }

    private int ROTR(int n, int x){
        return (x >>> n) | (x << (Integer.SIZE ­ n));
    }

    private int ROTL(int n, int x){
        return (x << n) | (x >>> (Integer.SIZE ­ n));
    }

    /*
    ∑{256}
0 (x) = ROTR 2
            (x) ⊕ ROTR 13(x) ⊕ ROTR 22(x)
            */

    private int capSigma0to256(int x){
        return ROTR(2, x) ^ ROTR(13, x) ^ ROTR(22, x);
    }

    private int capSigma1to256(int x){
        return ROTR(6,x) ^ ROTR(11, x) ^ ROTR(25, x);
    }

    private int sigma0to256(int x){
        return ROTR(7, x) ^ ROTR(18, x) ^ (x>>>3);
    }

    private int sigma1to256(int x){
        return ROTR(17, x) ^ ROTR(19, x) ^ (x>>>10);
    }

      public String calculateHash(String data){
          String preprocess=preprocess(data);
  
          int[] H ={0x6a09e667, 0xbb67ae85, 0x3c6ef372, 
0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
                   0x5be0cd19};    //initial hashes
  
          int blocks=preprocess.length()*8/512;
          String[] message_blocks=new String[blocks];
          for(int i=0;i<blocks;i++){
              message_blocks[i]=preprocess.substring(i*64, 
(i+1)*64);
          }
  
          for(int i=1;i<=blocks;i++){
              int[] message_schedule=new int[64];
              for(int j=0;j<16;j++){
                  int a=0x0000;
                  byte[] temp=message_blocks[i].substring(j*4, 
(j+1)*4).getBytes();
                  for(int k=0;k<4;k++){
                      int b=(int)temp[k];
  
                  }
              }
          }
          return null;
      }

    private String preprocess(String data){
        int l=data.length()*8;
        if(l%512==0) return data;

        int l_=l+1;
        int k=modulo((448­(modulo(l_,512))), 512);
        int pad_length=k+1;
        int pad_bytes=pad_length/8;
        char c=0x80;
        char b=0x00;
        String preprocessed=data+c;
        for(int i=0;i<pad_bytes­1;i++){
            preprocessed+=b;
        }
        return preprocessed;
    }
}
Problems solved

This block chain based voting system solves the problem of detecting data tampering
at every step. No adversary can tamper with any data in any block without disturbing
the entire chain. At every step data integrity of chain is checked and exception
thrown in case of data mismatch or tampering. This way the data is safe even when
it is stored in a database and on subsequent loads, its integrity will be checked to
ensure no tampering has been done.

You might also like