main.mx raw

   1  // The AEAD must produce the RFC 8439 ยง2.8.2 ciphertext when it is a dependency
   2  // of an application build, not only when its own package is the build root.
   3  package main
   4  
   5  import (
   6  	"fmt"
   7  
   8  	"golang.org/x/crypto/chacha20poly1305"
   9  )
  10  
  11  func unhex(s string) (b []byte) {
  12  	b = []byte{:len(s) / 2}
  13  	digit := func(c byte) (v byte, ok bool) {
  14  		switch {
  15  		case c >= '0' && c <= '9':
  16  			return c - '0', true
  17  		case c >= 'a' && c <= 'f':
  18  			return c - 'a' + 10, true
  19  		}
  20  		return 0, false
  21  	}
  22  	for i := int32(0); i < int32(len(b)); i++ {
  23  		hi, ok1 := digit(s[2*i])
  24  		lo, ok2 := digit(s[2*i+1])
  25  		if !ok1 || !ok2 {
  26  			return nil
  27  		}
  28  		b[i] = hi<<4 | lo
  29  	}
  30  	return
  31  }
  32  
  33  func main() {
  34  	key := unhex("808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f")
  35  	nonce := unhex("070000004041424344454647")
  36  	aad := unhex("50515253c0c1c2c3c4c5c6c7")
  37  	plaintext := []byte("Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.")
  38  	// Text joins with |, not +: '+' on text is a compile error in Moxie.
  39  	wantHex := "d31a8d34648e60db7b86afbc53ef7ec2" |
  40  		"a4aded51296e08fea9e2b5a736ee62d6" |
  41  		"3dbea45e8ca9671282fafb69da92728b" |
  42  		"1a71de0a9e060b2905d6a5b67ecd3b36" |
  43  		"92ddbd7f2d778b8c9803aee328091b58" |
  44  		"fab324e4fad675945585808b4831d7bc" |
  45  		"3ff4def08e4b7a9de576d26586cec64b" |
  46  		"6116" |
  47  		"1ae10b594f09e26a7e902ecbd0600691"
  48  	want := unhex(wantHex)
  49  	aead, err := chacha20poly1305.New(key)
  50  	if err != nil {
  51  		fmt.Printf("New failed: %s\n", err.Error())
  52  		return
  53  	}
  54  	ct := aead.Seal(nil, nonce, plaintext, aad)
  55  	if len(ct) != len(want) {
  56  		fmt.Printf("bad length: got %d want %d\n", int32(len(ct)), int32(len(want)))
  57  		return
  58  	}
  59  	for i := int32(0); i < int32(len(want)); i++ {
  60  		if ct[i] != want[i] {
  61  			fmt.Printf("MISMATCH at %d: got %02x want %02x (first=%02x)\n", i, int32(ct[i]), int32(want[i]), int32(ct[0]))
  62  			return
  63  		}
  64  	}
  65  	fmt.Printf("ok %02x %02x\n", int32(ct[0]), int32(ct[len(ct)-1]))
  66  }
  67