diff --git a/main.go b/main.go index 1e821b8..d68df66 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,8 @@ package main import ( "fmt" + "math" + "encoding/binary" "encoding/hex" "crypto/aes" "github.com/spf13/afero" @@ -32,4 +34,91 @@ func main() { fmt.Println(hex.EncodeToString(key)) fmt.Println(hex.EncodeToString(src)) fmt.Println(hex.EncodeToString(dest)) + + + fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") + nonce, err := hex.DecodeString("0011223344556677ffffffffffffffff") + if err != nil { + fmt.Println(err) + return + } + fmt.Println(hex.EncodeToString(nonce)) + newNonce := nonceAdd(nonce, 1) + fmt.Println(hex.EncodeToString(newNonce)) + newNonce = nonceAdd(newNonce, 1) + fmt.Println(hex.EncodeToString(newNonce)) + newNonce = nonceAdd(newNonce, 1) + fmt.Println(hex.EncodeToString(newNonce)) + newNonce = nonceAdd(newNonce, 1) + fmt.Println(hex.EncodeToString(newNonce)) + newNonce = nonceAdd(newNonce, 1) + fmt.Println(hex.EncodeToString(newNonce)) + newNonce = nonceAdd(newNonce, 1) + fmt.Println(hex.EncodeToString(newNonce)) + newNonce = nonceAdd(newNonce, 1) + fmt.Println(hex.EncodeToString(newNonce)) + + + fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") + test_key := []byte { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + } + test_iv := []byte { + 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, + } + plaintext := "hello world.hello world.hello world.hello world.hello world.hello world." + plaintextBytes := []byte(plaintext) + + e, err := generateCtrEncryptBytes(test_key, test_iv, 0, int64(len(plaintextBytes))) + if err != nil { + fmt.Println(err) + return + } + fmt.Println(hex.EncodeToString(e)) + for i := 0; i < len(plaintextBytes); i++ { + plaintextBytes[i] = plaintextBytes[i] ^ e[i] + } + // SHOULD BE: 84ad8d80732490c061177a58bd26d032d6fcff2e66f9afe3cf95717485d3a4485d4a2a7bd835df3d0756b8192e3bf5a287ad8dd81942c43bc812c82d666ebbb34df4e2a5069467d9 + fmt.Println(hex.EncodeToString(plaintextBytes)) +} + +func generateCtrEncryptBytes(key, iv []byte, offset, len int64) ([]byte, error) { + endOffset := offset + len + encryptStartOffset := (offset / 16) * 16 + encryptEndOffset := (endOffset / 16) * 16 + if endOffset % 16 > 0 { + encryptEndOffset += 16 + } + blocksCount := int((encryptEndOffset - encryptStartOffset) / 16) + + cipher, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + encryptBytes := make([]byte, blocksCount * 16) + for i := 0; i < blocksCount; i++ { + encNonce := nonceAdd(iv, uint64(i)) + cipher.Encrypt(encryptBytes[i*16:(i+1)*16], encNonce) + } + // fmt.Println("XX ", hex.EncodeToString(encryptBytes)) + return encryptBytes[offset-encryptStartOffset:offset-encryptStartOffset+len], nil +} + +func nonceAdd(nonce []byte, incrementValue uint64) []byte { + n1 := binary.BigEndian.Uint64(nonce[:8]) + n2 := binary.BigEndian.Uint64(nonce[8:]) + + leftToMax := math.MaxUint64 - n2 + if leftToMax <= incrementValue { + incrementValue -= leftToMax + 1 + n2 = incrementValue + n1 += 1 + } else { + n2 += incrementValue + } + + newNonce := make([]byte, 16) + binary.BigEndian.PutUint64(newNonce, n1) + binary.BigEndian.PutUint64(newNonce[8:], n2) + return newNonce }