ggstd 0.1.0

Partial implementation of Go standard library
Documentation
// Copyright 2023 The rust-ggstd authors.
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"crypto/aes"
	"crypto/cipher"
	"fmt"
)

func main() {
	key := []byte("0123456789abcdef")
	plaintext := []byte("hello world.....hello world.....hello world.....")

	fmt.Printf("plaintext:      %v\n", string(plaintext))
	aes_basic(key, plaintext)
	aes_cbc(key, plaintext)

	// in CTR mode plaintext doesn't have to be a multiple of the block size
	plaintext = []byte("hello world.....hello world.....hello worl")
	fmt.Printf("plaintext:      %v\n", string(plaintext))
	aes_ctr(key, plaintext)
}

func aes_basic(key []byte, plaintext []byte) {
	block, err := aes.NewCipher(key)
	if err != nil {
		fmt.Println("Error creating AES cipher block:", err)
		return
	}

	if len(plaintext)%aes.BlockSize != 0 {
		fmt.Println("Plaintext length must be a multiple of the block size")
		return
	}

	ciphertext := make([]byte, len(plaintext))

	for offset := 0; offset < len(plaintext); offset += aes.BlockSize {
		block.Encrypt(ciphertext[offset:offset+aes.BlockSize], plaintext[offset:offset+aes.BlockSize])
	}

	// decrypted := make([]byte, len(plaintext))
	// for offset := 0; offset < len(plaintext); offset += aes.BlockSize {
	// 	block.Decrypt(decrypted[offset:offset+aes.BlockSize], ciphertext[offset:offset+aes.BlockSize])
	// }

	// fmt.Printf("plaintext:      %v\n", string(plaintext))
	fmt.Printf("ECB encrypted:  %x\n", ciphertext)
	// fmt.Printf("decrypted:      %v\n", string(decrypted))
	// fmt.Println()
}

func aes_cbc(key []byte, plaintext []byte) {
	block, err := aes.NewCipher(key)
	if err != nil {
		fmt.Println("Error creating AES cipher block:", err)
		return
	}

	if len(plaintext)%aes.BlockSize != 0 {
		fmt.Println("Plaintext length must be a multiple of the block size")
		return
	}

	encrypted := make([]byte, len(plaintext))

	// Using the initialization vector of all zeroes for demo purposes.
	// In practice the IV should be unique for each encryption operation and upredictable,
	// for example, generated using a secure random generator.
	iv := make([]byte, aes.BlockSize)

	mode := cipher.NewCBCEncrypter(block, iv)

	mode.CryptBlocks(encrypted, plaintext)

	// decrypted := make([]byte, len(plaintext))
	// mode = cipher.NewCBCDecrypter(block, iv)
	// mode.CryptBlocks(decrypted, ciphertext)

	// fmt.Printf("plaintext:      %v\n", string(plaintext))
	fmt.Printf("CBC encrypted:  %x\n", encrypted)
	// fmt.Printf("decrypted:      %v\n", string(decrypted))
	// fmt.Println()
}

func aes_ctr(key []byte, plaintext []byte) {
	block, err := aes.NewCipher(key)
	if err != nil {
		fmt.Println("Error creating AES cipher:", err)
		return
	}

	// Using the initialization vector of all zeroes for demo purposes.
	// In practice the IV should be unique for each encryption operation and upredictable,
	// for example, generated using a secure random generator.
	iv := make([]byte, 16)

	stream := cipher.NewCTR(block, iv)

	encrypted := make([]byte, len(plaintext))
	stream.XORKeyStream(encrypted, plaintext)

	fmt.Printf("CTR encrypted:  %x\n", encrypted)

	// decrypted := make([]byte, len(encrypted))
	// stream = cipher.NewCTR(block, iv)
	// stream.XORKeyStream(decrypted, encrypted)
	// fmt.Printf("decrypted:      %v\n", string(decrypted))
}