mit-ocw

Source code for MIT-OCW coursework
git clone git://git.laack.co/mit-ocw.git
Log | Files | Refs

lamport.go (1798B)


      1 package main
      2 
      3 import (
      4 	"crypto/rand"
      5 	"crypto/sha256"
      6 	"fmt"
      7 )
      8 
      9 type Key struct {
     10 	firstRow  [256][32]byte
     11 	secondRow [256][32]byte
     12 }
     13 
     14 func GenerateKeys() (Key, Key) {
     15 
     16 	privateKey := Key{}
     17 
     18 	for i := range 256 {
     19 		_, err := rand.Read(privateKey.firstRow[i][:])
     20 		if err != nil {
     21 			panic(err)
     22 		}
     23 	}
     24 
     25 	for i := range 256 {
     26 		_, err := rand.Read(privateKey.secondRow[i][:])
     27 		if err != nil {
     28 			panic(err)
     29 		}
     30 	}
     31 
     32 	publicKey := Key{}
     33 
     34 	for i := range 256 {
     35 		publicKey.firstRow[i] = sha256.Sum256(privateKey.firstRow[i][:])
     36 	}
     37 
     38 	for i := range 256 {
     39 		publicKey.secondRow[i] = sha256.Sum256(privateKey.secondRow[i][:])
     40 
     41 	}
     42 
     43 	return publicKey, privateKey
     44 }
     45 
     46 func Sign(privateKey Key, message string) [256][32]byte {
     47 
     48 	messageHash := sha256.Sum256([]byte(message))
     49 
     50 	signature := [256][32]byte{}
     51 
     52 	for index := range 32 {
     53 		currentByteString := fmt.Sprintf("%08b", messageHash[index])
     54 		for idx := range 8 {
     55 			currentBit := currentByteString[idx]
     56 			if currentBit == '0' {
     57 				signature[(index*8)+idx] = privateKey.firstRow[(index*8)+idx]
     58 			} else {
     59 				signature[(index*8)+idx] = privateKey.secondRow[(index*8)+idx]
     60 			}
     61 		}
     62 	}
     63 
     64 	return signature
     65 }
     66 
     67 func Verify(publicKey Key, message string, signature [256][32]byte) bool {
     68 
     69 	messageHash := sha256.Sum256([]byte(message))
     70 
     71 	for index := range 32 {
     72 		currentByteString := fmt.Sprintf("%08b", messageHash[index])
     73 		for idx := range 8 {
     74 			currentBit := currentByteString[idx]
     75 			if currentBit == '0' {
     76 				// signature[(index * 8) + idx] = privateKey.firstRow[(index * 8) + idx]
     77 				if sha256.Sum256(signature[(index*8)+idx][:]) != publicKey.firstRow[(index*8)+idx] {
     78 					return false
     79 				}
     80 			} else {
     81 				if sha256.Sum256(signature[(index*8)+idx][:]) != publicKey.secondRow[(index*8)+idx] {
     82 					return false
     83 				}
     84 			}
     85 		}
     86 	}
     87 
     88 	return true
     89 
     90 }