Created
November 8, 2020 12:27
-
-
Save AmosAidoo/0b0f0af2e04fe4c42a2f9e320b4e245c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
) | |
// Sample test data for the algorithm | |
var ( | |
PLAIN_TEXT = []byte("Text") | |
KEY = []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") | |
) | |
func swap(x uint8, y uint8) (uint8, uint8) { | |
return y, x | |
} | |
func KSA() [256]byte { | |
var S [256]byte | |
var i int | |
// Initial RC4 state, S[i]=i, i=0, j=0 | |
j := 0 | |
for i = 0; i <= 255; i++ { | |
S[i] = byte(i) | |
} | |
// l := 64 as per the Programming Assignment document | |
l := len(KEY) | |
for i = 0; i <= 255; i++ { | |
j = (j + int(S[i]) + int(KEY[i % l])) % 256 | |
S[i], S[j] = swap(S[i], S[j]) | |
} | |
return S | |
} | |
func prga(S [256]byte) ([]uint8, [256]byte, int, int) { | |
i := 0 | |
j := 0 | |
var K []uint8 | |
for p:= 0; p < len(PLAIN_TEXT); p++ { | |
i = (i + 1) % 256 | |
j = (j + int(S[i])) % 256 | |
S[i], S[j] = swap(S[i], S[j]) | |
K = append(K, S[int((S[i] + S[j])) % 256]) | |
} | |
return K, S, i, j | |
} | |
func iprga(S_star [256]byte, i, j int) ([256]byte) { | |
for true { | |
S_star[i], S_star[j] = swap(S_star[i], S_star[j]) | |
j = (j - int(S_star[i]) + 256) % 256 | |
i = (i - 1) % 256 | |
if i < 0 || j < 0 { | |
break | |
} | |
} | |
return S_star | |
} | |
func compare(S1, S2 [256]byte) (bool) { | |
for i := 0; i < 256; i++ { | |
if S1[i] != S2[i] { | |
fmt.Println(i) | |
return false | |
} | |
} | |
return true | |
} | |
func main() { | |
S1 := KSA() | |
fmt.Println(S1) | |
// After applying PRGA we get S_star | |
_, S_star, i, j := prga(S1) | |
fmt.Println() | |
fmt.Println(S_star) | |
fmt.Println() | |
// After applying IPRGA to S_star we get back S | |
S2 := iprga(S_star, i, j) | |
fmt.Println(S2) | |
fmt.Println() | |
// Compare the output from IPRGA and IPRG | |
fmt.Printf("S1 = S2 [%v]", compare(S1, S2)) | |
fmt.Println() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"net" | |
"fmt" | |
"encoding/json" | |
) | |
func main() { | |
ln, _ := net.Listen("tcp", ":8080") | |
fmt.Println("Listening for connections at port 8080") | |
conn, err := ln.Accept() | |
if err != nil { | |
fmt.Println(err) | |
} | |
defer conn.Close() | |
securekey := []byte("Secure Key123456") | |
// RC4 State for the receiver | |
RC4State := KSA(securekey) | |
fmt.Printf("Connection received from %v\n", conn.RemoteAddr()) | |
// S1 := KSA([]byte("Key")) | |
// fmt.Println(S1) | |
// Initial SC of receiver | |
SC := 0 | |
for true { | |
var packet Packet | |
if err := json.NewDecoder(conn).Decode(&packet); err != nil { | |
// panic(err) | |
break | |
} | |
if SC - packet.SC == 0 { | |
var K []byte | |
// Keystream,new RC4 state, i and j | |
K, _, _, _ = Prga(RC4State, 252) //For data segment | |
// K1, _, _, _ = Prga(RC4State, 16) //For hash value | |
datasegment := decrypt(K, packet.DataSegment) | |
// hashvalue := decrypt(K1, packet.HashValue) | |
fmt.Println(string(datasegment)) | |
} else { | |
} | |
// fmt.Println(packet.DataSegment) | |
SC++ | |
} | |
// fmt.Printf("SC=%v\n",SC) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"strings" | |
"crypto/md5" | |
"strconv" | |
"net" | |
"encoding/json" | |
// "bufio" | |
// "os" | |
) | |
func main() { | |
/* | |
Inputs to this program are the plain text and secure key | |
*/ | |
// Read plaintext and securekey from stdin | |
// reader := bufio.NewReader(os.Stdin) | |
// plaintext = reader.ReadString("\n") | |
// securekey = reader.ReadString("\n") | |
// Attempt to connect to the receiver | |
conn, _ := net.Dial("tcp", "127.0.0.1:8080") | |
plaintext := "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. N" | |
securekey := []byte("Secure Key123456") | |
// RC4 State for the sender | |
RC4State := KSA(securekey) | |
l := len(plaintext) //Length of the plain text | |
n := (l + 252-1) / 252 //This is the number of packets to be sent | |
rem := ((n * 252) - l) //Find out if data segment is not enough | |
// fmt.Printf("rem = %v\n", rem) | |
// Append 1s and zeros if data segmant is not up to 252 bytes | |
if rem > 0 { | |
plaintext += "1" | |
plaintext += strings.Repeat("0", rem-1) | |
} | |
for sc := 0; sc < n; sc++ { | |
// Hash function used is MD5 | |
h := md5.New() | |
// Compute the hash by inputing the sc and the unencrypted data segment | |
fmt.Fprintf(h, strconv.Itoa(sc)) | |
fmt.Fprintf(h, plaintext[sc*252:(sc*252)+252]) | |
// var S [256]byte | |
var K, K1 []byte | |
// Keystream,new RC4 state, i and j | |
K, _, _, _ = Prga(RC4State, 252) //For data segment | |
K1, _, _, _ = Prga(RC4State, 16) //For hash value | |
packet := Packet{ | |
SC:sc, | |
DataSegment:encrypt(K, []byte(plaintext[sc*252:(sc*252)+252])), | |
HashValue: encrypt(K1, h.Sum(nil))} | |
fmt.Println(string(packet.DataSegment)) | |
if err := json.NewEncoder(conn).Encode(packet); err != nil { | |
panic(err) | |
} | |
// fmt.Fprintf() | |
} | |
fmt.Printf("% x\n", RC4State) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
type Packet struct { | |
SC int | |
DataSegment []byte | |
HashValue []byte | |
} | |
func swap(x uint8, y uint8) (uint8, uint8) { | |
return y, x | |
} | |
func KSA(key []byte) [256]byte { | |
var S [256]byte | |
var i int | |
// Initial RC4 state, S[i]=i, i=0, j=0 | |
j := 0 | |
for i = 0; i <= 255; i++ { | |
S[i] = byte(i) | |
} | |
l := len(key) | |
for i = 0; i <= 255; i++ { | |
j = (j + int(S[i]) + int(key[i % l])) % 256 | |
S[i], S[j] = swap(S[i], S[j]) | |
} | |
return S | |
} | |
func Prga(S [256]byte, length int) ([]byte, [256]byte, int, int) { | |
i := 0 | |
j := 0 | |
var K []byte | |
p := 0 | |
for p < length { | |
i = (i + 1) % 256 | |
j = (j + int(S[i])) % 256 | |
S[i], S[j] = swap(S[i], S[j]) | |
K = append(K, S[int((S[i] + S[j])) % 256]) | |
p++ | |
} | |
return K, S, i, j | |
} | |
func Iprga(S_star [256]byte, i, j int) ([256]byte) { | |
for true { | |
S_star[i], S_star[j] = swap(S_star[i], S_star[j]) | |
j = (j - int(S_star[i]) + 256) % 256 | |
i = (i - 1) % 256 | |
if i < 0 || j < 0 { | |
break | |
} | |
} | |
return S_star | |
} | |
func Compare(S1, S2 [256]byte) (bool) { | |
for i := 0; i < 256; i++ { | |
if S1[i] != S2[i] { | |
return false | |
} | |
} | |
return true | |
} | |
func encrypt(keystream []byte, datasegment []byte) []byte { | |
var cipherText []byte | |
for i := 0; i < len(keystream); i++ { | |
cipherText = append(cipherText, keystream[i] ^ datasegment[i]) | |
} | |
return cipherText | |
} | |
func decrypt(keystream []byte, cipherText []byte) []byte { | |
var datasegment []byte | |
for i := 0; i < len(keystream); i++ { | |
datasegment = append(datasegment, keystream[i] ^ cipherText[i]) | |
} | |
return datasegment | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment