Created
December 27, 2018 19:13
-
-
Save ptone/a7d29fa756b42bd2256fa28944cc2b1c to your computer and use it in GitHub Desktop.
chachapoly interop sanity check
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
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 | |
data = b"secret" | |
data = bytes([0x01,0x01,0x01,0x01,0x01,0x01]) | |
aad = b"1111111111111111" | |
aad = bytes([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]) | |
nonce = b"111111111111" # os.urandom(12) | |
nonce = bytes([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]) | |
test_key = ChaCha20Poly1305.generate_key() | |
key = bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | |
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, | |
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, | |
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38]) | |
chacha = ChaCha20Poly1305(key) | |
# nonce = os.urandom(12) | |
ct = chacha.encrypt(nonce, data, aad) | |
v = chacha.decrypt(nonce, ct, aad) | |
print(v) | |
print(len(ct)) | |
print(" ".join("{:02x}".format(x) for x in ct)) |
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
#include <Arduino.h> | |
#include <Crypto.h> | |
#include <ChaChaPoly.h> // https://rweather.github.io/arduinolibs/classChaChaPoly.html | |
#include <Base64.h> | |
#include <rBase64.h> | |
#define CHA_CHA_POLY_KEY_SIZE 32 | |
#define CHA_CHA_POLY_IV_SIZE 12 | |
#define CHA_CHA_POLY_AUTH_SIZE 16 | |
#define CHA_CHA_POLY_TAG_SIZE 16 | |
#define CHA_CHA_POLY_MESSAGE_SIZE 6 | |
ChaChaPoly chachapoly; | |
void encrypt(const byte key[CHA_CHA_POLY_KEY_SIZE], const byte iv[CHA_CHA_POLY_IV_SIZE], const byte auth[CHA_CHA_POLY_AUTH_SIZE], const byte plainText[CHA_CHA_POLY_MESSAGE_SIZE], byte cipherText[CHA_CHA_POLY_MESSAGE_SIZE], byte tag[CHA_CHA_POLY_TAG_SIZE]) | |
{ | |
chachapoly.clear(); | |
chachapoly.setKey(key, CHA_CHA_POLY_KEY_SIZE); | |
chachapoly.setIV(iv, CHA_CHA_POLY_IV_SIZE); | |
chachapoly.addAuthData(auth, CHA_CHA_POLY_AUTH_SIZE); | |
chachapoly.encrypt(cipherText, plainText, CHA_CHA_POLY_MESSAGE_SIZE); | |
chachapoly.computeTag(tag, CHA_CHA_POLY_TAG_SIZE); | |
} | |
bool decrypt(const byte key[CHA_CHA_POLY_KEY_SIZE], const byte iv[CHA_CHA_POLY_IV_SIZE], const byte auth[CHA_CHA_POLY_AUTH_SIZE], const byte cipherText[CHA_CHA_POLY_MESSAGE_SIZE], byte plainText[CHA_CHA_POLY_MESSAGE_SIZE], const byte tag[CHA_CHA_POLY_TAG_SIZE]) | |
{ | |
chachapoly.clear(); | |
chachapoly.setKey(key, CHA_CHA_POLY_KEY_SIZE); | |
chachapoly.setIV(iv, CHA_CHA_POLY_IV_SIZE); | |
chachapoly.addAuthData(auth, CHA_CHA_POLY_AUTH_SIZE); | |
chachapoly.decrypt(plainText, cipherText, CHA_CHA_POLY_MESSAGE_SIZE); | |
return chachapoly.checkTag(tag, CHA_CHA_POLY_TAG_SIZE); | |
} | |
void setup() { | |
// put your setup code here, to run once: | |
Serial.begin(115200); | |
delay(1500); | |
Serial.print("Testing ecc\n"); | |
byte key[CHA_CHA_POLY_KEY_SIZE] = { | |
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | |
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, | |
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, | |
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}; | |
byte iv[CHA_CHA_POLY_IV_SIZE] = {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}; | |
// construct plain text message | |
byte plainText[CHA_CHA_POLY_MESSAGE_SIZE] = {0x01,0x01,0x01,0x01,0x01,0x01}; | |
byte decrypted[CHA_CHA_POLY_MESSAGE_SIZE]; | |
// String plain = "secret"; | |
// plain.getBytes(plainText, CHA_CHA_POLY_MESSAGE_SIZE); | |
// Serial.print("got bytes \n"); | |
// set additional auth data | |
byte aad[16] = {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}; | |
byte cipherText[CHA_CHA_POLY_MESSAGE_SIZE]; | |
byte tag[CHA_CHA_POLY_TAG_SIZE]; | |
encrypt(key, iv, aad, plainText, cipherText, tag); | |
Serial.println("plain"); | |
Serial.println(sizeof(plainText)); | |
for (int i=0; i<CHA_CHA_POLY_MESSAGE_SIZE; i++) { | |
Serial.print(" "); | |
Serial.print(plainText[i], HEX); | |
} | |
Serial.println(); | |
Serial.println(); | |
Serial.println("encrypted"); | |
Serial.println(sizeof(cipherText)); | |
for (int i=0; i<CHA_CHA_POLY_MESSAGE_SIZE; i++) { | |
Serial.print(" "); | |
Serial.print(cipherText[i], HEX); | |
} | |
Serial.println(); | |
Serial.println(); | |
Serial.println("tag"); | |
Serial.println(sizeof(tag)); | |
for (int i=0; i<CHA_CHA_POLY_TAG_SIZE; i++) { | |
Serial.print(" "); | |
Serial.print(tag[i], HEX); | |
} | |
Serial.println(); | |
Serial.println(); | |
// base64 encoding | |
Serial.println("encoding: "); | |
int inputStringLength = sizeof(cipherText); | |
int encodedLength = Base64.encodedLength(inputStringLength); | |
char encodedString[encodedLength]; | |
// this line was key and eluded me for a long time | |
char* cipherchar = reinterpret_cast<char*>(cipherText); | |
Base64.encode(encodedString, cipherchar, inputStringLength); | |
Serial.print("Encoded string is:\n"); | |
Serial.println(encodedString); | |
if (rbase64.encode(cipherchar) == RBASE64_STATUS_OK) { | |
Serial.println("\nConverted the String to Base64 : "); | |
Serial.println(rbase64.result()); | |
Serial.println(strlen(cipherchar)); | |
} | |
// decrypt message from cipherText to plainText | |
// output is valid only if result is true | |
bool result = decrypt(key, iv, aad, cipherText, decrypted, tag); | |
if (result) { | |
Serial.println("decrypt ok:"); | |
// String dmsg = (char*)decrypted; | |
// Serial.println(dmsg); | |
for (int i=0; i<CHA_CHA_POLY_MESSAGE_SIZE; i++) { | |
// Serial.print(", 0x"); | |
Serial.print(" "); | |
Serial.print(decrypted[i], HEX); | |
} | |
} else { | |
Serial.println("decrypt failed in some way"); | |
} | |
} | |
void loop() { | |
// put your main code here, to run repeatedly: | |
} |
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
var chacha = require('chacha'); | |
// https://github.com/calvinmetcalf/chacha20poly1305 | |
const key = Buffer.from([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | |
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, | |
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, | |
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38]); | |
const nonce = Buffer.from([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]) | |
const aad = Buffer.from([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]) | |
const secret = Buffer.from([0x01,0x01,0x01,0x01,0x01,0x01]) | |
var cipher = chacha.createCipher(key, nonce); | |
cipher.setAAD(aad); | |
const ciphertext = cipher.update(secret); | |
cipher.final(); | |
var tag = cipher.getAuthTag();// must be called after finish or end | |
console.log(ciphertext); | |
console.log(tag); | |
var decipher = chacha.createDecipher(key, nonce); |
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 ( | |
"encoding/base64" | |
"fmt" | |
"log" | |
"golang.org/x/crypto/chacha20poly1305" | |
) | |
//using 8byte nonce | |
// var enc = "NJ3ENqqtKtWkKplMmNhW6xeEj6gID5B1fILh9JVT5JnyT7D4S1bC4uHGXr4un6KgbDg7BYDDdMI2eykr" | |
// using 12 byte nonce | |
// var enc = "ej0sf8MpWNw+9532JJFhSbRK8QXDLzYI8aqymboTdVOF1T6nXtel/A3PbpvSLAKP+qhENx6OCrjlWd2c" | |
var enc = "ej0lYsMpWNw+9532JJFhSbRK8QXDL9+i3Wtv21DgQ3awx7EGUxaWSNgZGxofXDSewVbpTA6OCrgUpiJj" | |
var key = []byte{ | |
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | |
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, | |
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, | |
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38} | |
// byte auth[CHA_CHA_POLY_AUTH_SIZE] = { | |
// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | |
// 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; | |
// var iv = []byte{1, 1, 1, 1, 1, 1, 1, 1} | |
var iv = []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} | |
var aad = []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} | |
func reverse(numbers []byte) []byte { | |
for i := 0; i < len(numbers)/2; i++ { | |
j := len(numbers) - i - 1 | |
numbers[i], numbers[j] = numbers[j], numbers[i] | |
} | |
return numbers | |
} | |
func main() { | |
ciphertext, err := base64.StdEncoding.DecodeString(enc) | |
if err != nil { | |
log.Fatal("decode failed") | |
} | |
// log.Println(ciphertext) | |
// var key2 []byte | |
// key2 = reverse(key) | |
chacha, err := chacha20poly1305.New(key) | |
if err != nil { | |
log.Fatal("chacha init failed") | |
} | |
// Decryption. | |
plaintext, err := chacha.Open(nil, iv, ciphertext, aad) | |
if err != nil { | |
for _, x := range ciphertext { | |
// fmt.Printf("%02x ", x) | |
fmt.Printf("%x ", x) | |
} | |
fmt.Println() | |
fmt.Println(len(ciphertext)) | |
log.Println("Failed to decrypt or authenticate message:", err) | |
} | |
fmt.Printf("%s\n", plaintext) | |
fmt.Println("Part 2") | |
// plain2 := []byte("secret") | |
plain2 := []byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01} | |
chacha2, err := chacha20poly1305.New(key) | |
cipher2 := chacha2.Seal(nil, iv, plain2, aad) | |
plain2opened, err := chacha2.Open(nil, iv, cipher2, aad) | |
if err != nil { | |
for _, x := range cipher2 { | |
// fmt.Printf("%02x ", x) | |
fmt.Printf("%x ", x) | |
} | |
fmt.Println() | |
fmt.Println(len(cipher2)) | |
log.Println("Failed to decrypt or authenticate message:", err) | |
} else { | |
fmt.Println("oh boy") | |
} | |
fmt.Println(string(plain2opened)) | |
for _, x := range cipher2 { | |
fmt.Printf("%02x ", x) | |
// fmt.Printf("%x ", x) | |
} | |
fmt.Println() | |
fmt.Println(len(cipher2)) | |
} |
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
The full payload is ciphertext of 6 bytes + tag of 16 bytes | |
The AAD extra data is included in tag, but not in ciphertext - it acts as a second verification factor | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment