Regenerated dependencies with Godep

This commit is contained in:
silenteh 2016-01-26 14:50:04 +01:00
parent 8199ae9abf
commit 9e163709ba
42 changed files with 1296 additions and 1700 deletions

26
Godeps/Godeps.json generated
View File

@ -1,16 +1,16 @@
{ {
"ImportPath": "github.com/sec51/twofactor", "ImportPath": "github.com/sec51/twofactor",
"GoVersion": "go1.5.1", "GoVersion": "go1.5.3",
"Deps": [ "Deps": [
{ {
"ImportPath": "code.google.com/p/rsc/gf256", "ImportPath": "code.google.com/p/rsc/gf256",
"Comment": "null-258", "Comment": "null-258",
"Rev": "2d8aa6027fab93979a3b4ecdbeb1ba430b489318" "Rev": "'2d8aa6027fab93979a3b4ecdbeb1ba430b489318'"
}, },
{ {
"ImportPath": "code.google.com/p/rsc/qr", "ImportPath": "code.google.com/p/rsc/qr/coding",
"Comment": "null-258", "Comment": "null-258",
"Rev": "2d8aa6027fab93979a3b4ecdbeb1ba430b489318" "Rev": "'2d8aa6027fab93979a3b4ecdbeb1ba430b489318'"
}, },
{ {
"ImportPath": "github.com/sec51/convert/smallendian", "ImportPath": "github.com/sec51/convert/smallendian",
@ -18,31 +18,35 @@
}, },
{ {
"ImportPath": "github.com/sec51/cryptoengine", "ImportPath": "github.com/sec51/cryptoengine",
"Rev": "b1ace081988c205e343d4c0b5b026921c9ad0081" "Rev": "e498a1921e25d2b08a85cadc66e3e0c3e0763129"
},
{
"ImportPath": "github.com/sec51/rsc/qr",
"Rev": "ccfe198e06521e3835029dbdd1ee3ecd799aa049"
}, },
{ {
"ImportPath": "golang.org/x/crypto/curve25519", "ImportPath": "golang.org/x/crypto/curve25519",
"Rev": "83f1503f771a82af8a31f358eb825e9efb5dae6c" "Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
}, },
{ {
"ImportPath": "golang.org/x/crypto/hkdf", "ImportPath": "golang.org/x/crypto/hkdf",
"Rev": "83f1503f771a82af8a31f358eb825e9efb5dae6c" "Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
}, },
{ {
"ImportPath": "golang.org/x/crypto/nacl/box", "ImportPath": "golang.org/x/crypto/nacl/box",
"Rev": "83f1503f771a82af8a31f358eb825e9efb5dae6c" "Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
}, },
{ {
"ImportPath": "golang.org/x/crypto/nacl/secretbox", "ImportPath": "golang.org/x/crypto/nacl/secretbox",
"Rev": "83f1503f771a82af8a31f358eb825e9efb5dae6c" "Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
}, },
{ {
"ImportPath": "golang.org/x/crypto/poly1305", "ImportPath": "golang.org/x/crypto/poly1305",
"Rev": "83f1503f771a82af8a31f358eb825e9efb5dae6c" "Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
}, },
{ {
"ImportPath": "golang.org/x/crypto/salsa20/salsa", "ImportPath": "golang.org/x/crypto/salsa20/salsa",
"Rev": "83f1503f771a82af8a31f358eb825e9efb5dae6c" "Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
} }
] ]
} }

27
Godeps/_workspace/src/code.google.com/p/rsc/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,85 +0,0 @@
// Copyright 2012 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.
// This file contains a straightforward implementation of
// Reed-Solomon encoding, along with a benchmark.
// It goes with http://research.swtch.com/field.
//
// For an optimized implementation, see gf256.go.
package gf256
import (
"bytes"
"fmt"
"testing"
)
// BlogECC writes to check the error correcting code bytes
// for data using the given Reed-Solomon parameters.
func BlogECC(rs *RSEncoder, m []byte, check []byte) {
if len(check) < rs.c {
panic("gf256: invalid check byte length")
}
if rs.c == 0 {
return
}
// The check bytes are the remainder after dividing
// data padded with c zeros by the generator polynomial.
// p = data padded with c zeros.
var p []byte
n := len(m) + rs.c
if len(rs.p) >= n {
p = rs.p
} else {
p = make([]byte, n)
}
copy(p, m)
for i := len(m); i < len(p); i++ {
p[i] = 0
}
gen := rs.gen
// Divide p by gen, leaving the remainder in p[len(data):].
// p[0] is the most significant term in p, and
// gen[0] is the most significant term in the generator.
for i := 0; i < len(m); i++ {
k := f.Mul(p[i], f.Inv(gen[0])) // k = pi / g0
// p -= k·g
for j, g := range gen {
p[i+j] = f.Add(p[i+j], f.Mul(k, g))
}
}
copy(check, p[len(m):])
rs.p = p
}
func BenchmarkBlogECC(b *testing.B) {
data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
check := []byte{0x29, 0x41, 0xb3, 0x93, 0x8, 0xe8, 0xa3, 0xe7, 0x63, 0x8f}
out := make([]byte, len(check))
rs := NewRSEncoder(f, len(check))
for i := 0; i < b.N; i++ {
BlogECC(rs, data, out)
}
b.SetBytes(int64(len(data)))
if !bytes.Equal(out, check) {
fmt.Printf("have %#v want %#v\n", out, check)
}
}
func TestBlogECC(t *testing.T) {
data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
check := []byte{0xa5, 0x24, 0xd4, 0xc1, 0xed, 0x36, 0xc7, 0x87, 0x2c, 0x55}
out := make([]byte, len(check))
rs := NewRSEncoder(f, len(check))
BlogECC(rs, data, out)
if !bytes.Equal(out, check) {
t.Errorf("have %x want %x", out, check)
}
}

View File

@ -1,194 +0,0 @@
// Copyright 2010 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 gf256
import (
"bytes"
"fmt"
"testing"
)
var f = NewField(0x11d, 2) // x^8 + x^4 + x^3 + x^2 + 1
func TestBasic(t *testing.T) {
if f.Exp(0) != 1 || f.Exp(1) != 2 || f.Exp(255) != 1 {
panic("bad Exp")
}
}
func TestECC(t *testing.T) {
data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
check := []byte{0xa5, 0x24, 0xd4, 0xc1, 0xed, 0x36, 0xc7, 0x87, 0x2c, 0x55}
out := make([]byte, len(check))
rs := NewRSEncoder(f, len(check))
rs.ECC(data, out)
if !bytes.Equal(out, check) {
t.Errorf("have %x want %x", out, check)
}
}
func TestLinear(t *testing.T) {
d1 := []byte{0x00, 0x00}
c1 := []byte{0x00, 0x00}
out := make([]byte, len(c1))
rs := NewRSEncoder(f, len(c1))
if rs.ECC(d1, out); !bytes.Equal(out, c1) {
t.Errorf("ECBytes(%x, %d) = %x, want 0", d1, len(c1), out)
}
d2 := []byte{0x00, 0x01}
c2 := make([]byte, 2)
rs.ECC(d2, c2)
d3 := []byte{0x00, 0x02}
c3 := make([]byte, 2)
rs.ECC(d3, c3)
cx := make([]byte, 2)
for i := range cx {
cx[i] = c2[i] ^ c3[i]
}
d4 := []byte{0x00, 0x03}
c4 := make([]byte, 2)
rs.ECC(d4, c4)
if !bytes.Equal(cx, c4) {
t.Errorf("ECBytes(%x, 2) = %x\nECBytes(%x, 2) = %x\nxor = %x\nECBytes(%x, 2) = %x",
d2, c2, d3, c3, cx, d4, c4)
}
}
func TestGaussJordan(t *testing.T) {
rs := NewRSEncoder(f, 2)
m := make([][]byte, 16)
for i := range m {
m[i] = make([]byte, 4)
m[i][i/8] = 1 << uint(i%8)
rs.ECC(m[i][:2], m[i][2:])
}
if false {
fmt.Printf("---\n")
for _, row := range m {
fmt.Printf("%x\n", row)
}
}
b := []uint{0, 1, 2, 3, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27}
for i := 0; i < 16; i++ {
bi := b[i]
if m[i][bi/8]&(1<<(7-bi%8)) == 0 {
for j := i + 1; ; j++ {
if j >= len(m) {
t.Errorf("lost track for %d", bi)
break
}
if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
m[i], m[j] = m[j], m[i]
break
}
}
}
for j := i + 1; j < len(m); j++ {
if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
for k := range m[j] {
m[j][k] ^= m[i][k]
}
}
}
}
if false {
fmt.Printf("---\n")
for _, row := range m {
fmt.Printf("%x\n", row)
}
}
for i := 15; i >= 0; i-- {
bi := b[i]
for j := i - 1; j >= 0; j-- {
if m[j][bi/8]&(1<<(7-bi%8)) != 0 {
for k := range m[j] {
m[j][k] ^= m[i][k]
}
}
}
}
if false {
fmt.Printf("---\n")
for _, row := range m {
fmt.Printf("%x", row)
out := make([]byte, 2)
if rs.ECC(row[:2], out); !bytes.Equal(out, row[2:]) {
fmt.Printf(" - want %x", out)
}
fmt.Printf("\n")
}
}
}
func BenchmarkECC(b *testing.B) {
data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
check := []byte{0x29, 0x41, 0xb3, 0x93, 0x8, 0xe8, 0xa3, 0xe7, 0x63, 0x8f}
out := make([]byte, len(check))
rs := NewRSEncoder(f, len(check))
for i := 0; i < b.N; i++ {
rs.ECC(data, out)
}
b.SetBytes(int64(len(data)))
if !bytes.Equal(out, check) {
fmt.Printf("have %#v want %#v\n", out, check)
}
}
func TestGen(t *testing.T) {
for i := 0; i < 256; i++ {
_, lg := f.gen(i)
if lg[0] != 0 {
t.Errorf("#%d: %x", i, lg)
}
}
}
func TestReducible(t *testing.T) {
var count = []int{1, 2, 3, 6, 9, 18, 30, 56, 99, 186} // oeis.org/A1037
for i, want := range count {
n := 0
for p := 1 << uint(i+2); p < 1<<uint(i+3); p++ {
if !reducible(p) {
n++
}
}
if n != want {
t.Errorf("#reducible(%d-bit) = %d, want %d", i+2, n, want)
}
}
}
func TestExhaustive(t *testing.T) {
for poly := 0x100; poly < 0x200; poly++ {
if reducible(poly) {
continue
}
α := 2
for !generates(α, poly) {
α++
}
f := NewField(poly, α)
for p := 0; p < 256; p++ {
for q := 0; q < 256; q++ {
fm := int(f.Mul(byte(p), byte(q)))
pm := mul(p, q, poly)
if fm != pm {
t.Errorf("NewField(%#x).Mul(%#x, %#x) = %#x, want %#x", poly, p, q, fm, pm)
}
}
}
}
}
func generates(α, poly int) bool {
x := α
for i := 0; i < 254; i++ {
if x == 1 {
return false
}
x = mul(x, α, poly)
}
return true
}

View File

@ -1,133 +0,0 @@
// Copyright 2011 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 coding
import (
"bytes"
"testing"
"code.google.com/p/rsc/gf256"
"code.google.com/p/rsc/qr/libqrencode"
)
func test(t *testing.T, v Version, l Level, text ...Encoding) bool {
s := ""
ty := libqrencode.EightBit
switch x := text[0].(type) {
case String:
s = string(x)
case Alpha:
s = string(x)
ty = libqrencode.Alphanumeric
case Num:
s = string(x)
ty = libqrencode.Numeric
}
key, err := libqrencode.Encode(libqrencode.Version(v), libqrencode.Level(l), ty, s)
if err != nil {
t.Errorf("libqrencode.Encode(%v, %v, %d, %#q): %v", v, l, ty, s, err)
return false
}
mask := (^key.Pixel[8][2]&1)<<2 | (key.Pixel[8][3]&1)<<1 | (^key.Pixel[8][4] & 1)
p, err := NewPlan(v, l, Mask(mask))
if err != nil {
t.Errorf("NewPlan(%v, L, %d): %v", v, err, mask)
return false
}
if len(p.Pixel) != len(key.Pixel) {
t.Errorf("%v: NewPlan uses %dx%d, libqrencode uses %dx%d", v, len(p.Pixel), len(p.Pixel), len(key.Pixel), len(key.Pixel))
return false
}
c, err := p.Encode(text...)
if err != nil {
t.Errorf("Encode: %v", err)
return false
}
badpix := 0
Pixel:
for y, prow := range p.Pixel {
for x, pix := range prow {
pix &^= Black
if c.Black(x, y) {
pix |= Black
}
keypix := key.Pixel[y][x]
want := Pixel(0)
switch {
case keypix&libqrencode.Finder != 0:
want = Position.Pixel()
case keypix&libqrencode.Alignment != 0:
want = Alignment.Pixel()
case keypix&libqrencode.Timing != 0:
want = Timing.Pixel()
case keypix&libqrencode.Format != 0:
want = Format.Pixel()
want |= OffsetPixel(pix.Offset()) // sic
want |= pix & Invert
case keypix&libqrencode.PVersion != 0:
want = PVersion.Pixel()
case keypix&libqrencode.DataECC != 0:
if pix.Role() == Check || pix.Role() == Extra {
want = pix.Role().Pixel()
} else {
want = Data.Pixel()
}
want |= OffsetPixel(pix.Offset())
want |= pix & Invert
default:
want = Unused.Pixel()
}
if keypix&libqrencode.Black != 0 {
want |= Black
}
if pix != want {
t.Errorf("%v/%v: Pixel[%d][%d] = %v, want %v %#x", v, mask, y, x, pix, want, keypix)
if badpix++; badpix >= 100 {
t.Errorf("stopping after %d bad pixels", badpix)
break Pixel
}
}
}
}
return badpix == 0
}
var input = []Encoding{
String("hello"),
Num("1"),
Num("12"),
Num("123"),
Alpha("AB"),
Alpha("ABC"),
}
func TestVersion(t *testing.T) {
badvers := 0
Version:
for v := Version(1); v <= 40; v++ {
for l := L; l <= H; l++ {
for _, in := range input {
if !test(t, v, l, in) {
if badvers++; badvers >= 10 {
t.Errorf("stopping after %d bad versions", badvers)
break Version
}
}
}
}
}
}
func TestEncode(t *testing.T) {
data := []byte{0x10, 0x20, 0x0c, 0x56, 0x61, 0x80, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11, 0xec, 0x11}
check := []byte{0xa5, 0x24, 0xd4, 0xc1, 0xed, 0x36, 0xc7, 0x87, 0x2c, 0x55}
rs := gf256.NewRSEncoder(Field, len(check))
out := make([]byte, len(check))
rs.ECC(data, out)
if !bytes.Equal(out, check) {
t.Errorf("have %x want %x", out, check)
}
}

View File

@ -1,73 +0,0 @@
// Copyright 2011 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 qr
import (
"bytes"
"image"
"image/color"
"image/png"
"io/ioutil"
"testing"
)
func TestPNG(t *testing.T) {
c, err := Encode("hello, world", L)
if err != nil {
t.Fatal(err)
}
pngdat := c.PNG()
if true {
ioutil.WriteFile("x.png", pngdat, 0666)
}
m, err := png.Decode(bytes.NewBuffer(pngdat))
if err != nil {
t.Fatal(err)
}
gm := m.(*image.Gray)
scale := c.Scale
siz := c.Size
nbad := 0
for y := 0; y < scale*(8+siz); y++ {
for x := 0; x < scale*(8+siz); x++ {
v := byte(255)
if c.Black(x/scale-4, y/scale-4) {
v = 0
}
if gv := gm.At(x, y).(color.Gray).Y; gv != v {
t.Errorf("%d,%d = %d, want %d", x, y, gv, v)
if nbad++; nbad >= 20 {
t.Fatalf("too many bad pixels")
}
}
}
}
}
func BenchmarkPNG(b *testing.B) {
c, err := Encode("0123456789012345678901234567890123456789", L)
if err != nil {
panic(err)
}
var bytes []byte
for i := 0; i < b.N; i++ {
bytes = c.PNG()
}
b.SetBytes(int64(len(bytes)))
}
func BenchmarkImagePNG(b *testing.B) {
c, err := Encode("0123456789012345678901234567890123456789", L)
if err != nil {
panic(err)
}
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
png.Encode(&buf, c.Image())
}
b.SetBytes(int64(buf.Len()))
}

View File

@ -1,61 +0,0 @@
package smallendian
import (
"encoding/binary"
"testing"
)
func TestSmallEndianUint64(t *testing.T) {
// convert ot bytes
input := uint64(2984983220)
inputBytes := ToUint64(input)
// convert from bytes back
result := FromUint64(inputBytes)
if result != input {
t.Errorf("Small endian conversion failed. Got %d instead of %d\n", result, input)
}
goResult := binary.LittleEndian.Uint64(inputBytes[:])
if goResult != input {
t.Fatal("It's not a small endian representation")
}
input = uint64(18446744073709551615)
inputBytes = ToUint64(input)
// convert from bytes back
result = FromUint64(inputBytes)
if result != input {
t.Fatal("Small endian conversion failed")
}
goResult = binary.LittleEndian.Uint64(inputBytes[:])
if goResult != input {
t.Fatal("It's not a small endian representation")
}
}
func TestSmallEndianInt(t *testing.T) {
// convert ot bytes
input := int(2984983220)
inputBytes := ToInt(input)
// convert from bytes back
result := FromInt(inputBytes)
if result != input {
t.Fatal("Small endian conversion failed")
}
goResult := binary.LittleEndian.Uint32(inputBytes[:])
if int(goResult) != input {
t.Fatal("It's not a small endian representation")
}
}

View File

@ -1,7 +1,9 @@
language: go language: go
go: go:
- 1.4 - 1.5
sudo: required
install: install:
- go get "golang.org/x/crypto/nacl/box" - go get "golang.org/x/crypto/nacl/box"
@ -9,4 +11,4 @@ install:
- go get "github.com/sec51/convert" - go get "github.com/sec51/convert"
script: script:
- go test -v ./... - go test -v -race ./...

View File

@ -0,0 +1,34 @@
{
"ImportPath": "github.com/sec51/cryptoengine",
"GoVersion": "go1.5.1",
"Deps": [
{
"ImportPath": "github.com/sec51/convert/smallendian",
"Rev": "8ed1f399b5e0a9a9620c74cfd5aec3682d8328ab"
},
{
"ImportPath": "golang.org/x/crypto/curve25519",
"Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
},
{
"ImportPath": "golang.org/x/crypto/hkdf",
"Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
},
{
"ImportPath": "golang.org/x/crypto/nacl/box",
"Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
},
{
"ImportPath": "golang.org/x/crypto/nacl/secretbox",
"Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
},
{
"ImportPath": "golang.org/x/crypto/poly1305",
"Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
},
{
"ImportPath": "golang.org/x/crypto/salsa20/salsa",
"Rev": "beef0f4390813b96e8e68fd78570396d0f4751fc"
}
]
}

View File

@ -0,0 +1,5 @@
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.

View File

@ -15,7 +15,7 @@ The encryption and decryption phases are the following:
``` ```
Message -> Encrypt -> EncryptedMessage -> < = NETWORK = > <- EncryptedMessage -> Descrypt -> Message Message -> Encrypt -> EncryptedMessage -> ToBytes() -> < = NETWORK = > <- FromBytes() -> EncryptedMessage -> Decrypt -> Message
``` ```

View File

@ -3,22 +3,24 @@ package cryptoengine
import ( import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"crypto/sha256"
"errors" "errors"
"fmt" "fmt"
"golang.org/x/crypto/nacl/box" "golang.org/x/crypto/nacl/box"
"golang.org/x/crypto/nacl/secretbox" "golang.org/x/crypto/nacl/secretbox"
"log" "log"
"math"
"net/url" "net/url"
"regexp" "regexp"
"strconv"
"strings" "strings"
"sync"
) )
const ( const (
// secretKeyVersion = 0 // this is the symmetric encryption version
// publicKeyVersion = 1 // this is the asymmetric encryption version
nonceSize = 24 // this is the nonce size, required by NaCl nonceSize = 24 // this is the nonce size, required by NaCl
keySize = 32 // this is the nonce size, required by NaCl keySize = 32 // this is the nonce size, required by NaCl
rotateSaltAfterDays = 2 // this is the amount of days the salt is valid - if it crosses this amount a new salt is generated rotateSaltAfterDays = 7 // this is the amount of days the salt is valid - if it crosses this amount a new salt is generated
tcpVersion = 0 // this is the current TCP version tcpVersion = 0 // this is the current TCP version
) )
@ -52,15 +54,16 @@ var (
// The object has the methods necessary to execute all the needed functions to encrypt and decrypt a message, both with symmetric and asymmetric // The object has the methods necessary to execute all the needed functions to encrypt and decrypt a message, both with symmetric and asymmetric
// crypto // crypto
type CryptoEngine struct { type CryptoEngine struct {
context string // this is the context used for the key derivation function and for namespacing the key files context string // this is the context used for the key derivation function and for namespacing the key files
publicKey [keySize]byte // cached asymmetric public key publicKey [keySize]byte // cached asymmetric public key
privateKey [keySize]byte // cached asymmetric private key privateKey [keySize]byte // cached asymmetric private key
secretKey [keySize]byte // secret key used for symmetric encryption secretKey [keySize]byte // secret key used for symmetric encryption
peerPublicKey [keySize]byte // the peer symmetric public key salt [keySize]byte // salt for deriving the random nonces
sharedKey [keySize]byte // this is the precomputed key, between the peer aymmetric public key and the application asymmetric private key. This speeds up things. nonceKey [keySize]byte // this key is used for deriving the random nonces. It's different from the privateKey
salt [keySize]byte // salt for deriving the random nonces mutex sync.Mutex // this mutex is used ti make sure that in case the engine is used by multiple thread the pre-shared key is correctly generated
nonceKey [keySize]byte // this key is used for deriving the random nonces. It's different from the privateKey preSharedKeysMap map[string][keySize]byte // this map holds the combination hash of peer public key as the map key and the preshared key as value used to encrypt
preSharedInitialized bool // flag which tells if the preSharedKey has been initialized counter uint64 // this is the counter which is appended to the HKDF at each call
counterMutex sync.Mutex // this is the counter mutex for a safe incrementation (TODO: look into atomic)
} }
// This function initialize all the necessary information to carry out a secure communication // This function initialize all the necessary information to carry out a secure communication
@ -79,7 +82,6 @@ func InitCryptoEngine(communicationIdentifier string) (*CryptoEngine, error) {
var err error var err error
// create a new crypto engine object // create a new crypto engine object
ce := new(CryptoEngine) ce := new(CryptoEngine)
ce.preSharedInitialized = false
// sanitize the communicationIdentifier // sanitize the communicationIdentifier
ce.context = sanitizeIdentifier(communicationIdentifier) ce.context = sanitizeIdentifier(communicationIdentifier)
@ -111,6 +113,9 @@ func InitCryptoEngine(communicationIdentifier string) (*CryptoEngine, error) {
} }
ce.nonceKey = nonceKey ce.nonceKey = nonceKey
// init the map
ce.preSharedKeysMap = make(map[string][keySize]byte)
// finally return the CryptoEngine instance // finally return the CryptoEngine instance
return ce, nil return ce, nil
@ -301,6 +306,25 @@ func sanitizeIdentifier(id string) string {
return cleaned return cleaned
} }
func (engine *CryptoEngine) fetchAndIncrement() string {
engine.counterMutex.Lock()
defer engine.counterMutex.Unlock()
// first read the current value
// reset the counter
if engine.counter == math.MaxUint64 {
engine.counter = 0
}
// convert the counter to string
counterString := strconv.FormatUint(engine.counter, 10)
// increment the counter
engine.counter += 1
return counterString
}
// Gives access to the public key // Gives access to the public key
func (engine *CryptoEngine) PublicKey() []byte { func (engine *CryptoEngine) PublicKey() []byte {
return engine.publicKey[:] return engine.publicKey[:]
@ -312,7 +336,7 @@ func (engine *CryptoEngine) NewEncryptedMessage(msg message) (EncryptedMessage,
m := EncryptedMessage{} m := EncryptedMessage{}
// derive nonce // derive nonce
nonce, err := deriveNonce(engine.nonceKey, engine.salt, engine.context) nonce, err := deriveNonce(engine.nonceKey, engine.salt, engine.context, engine.fetchAndIncrement())
if err != nil { if err != nil {
return m, err return m, err
} }
@ -325,7 +349,7 @@ func (engine *CryptoEngine) NewEncryptedMessage(msg message) (EncryptedMessage,
m.data = encryptedData m.data = encryptedData
// calculate the overall size of the message // calculate the overall size of the message
m.length = uint64(len(m.data) + len(m.nonce)) m.length = uint64(len(m.data) + len(m.nonce) + 8)
return m, nil return m, nil
@ -336,54 +360,73 @@ func (engine *CryptoEngine) NewEncryptedMessage(msg message) (EncryptedMessage,
// If the public key is not privisioned and does not have the required length of 32 bytes it raises an exception. // If the public key is not privisioned and does not have the required length of 32 bytes it raises an exception.
func (engine *CryptoEngine) NewEncryptedMessageWithPubKey(msg message, verificationEngine VerificationEngine) (EncryptedMessage, error) { func (engine *CryptoEngine) NewEncryptedMessageWithPubKey(msg message, verificationEngine VerificationEngine) (EncryptedMessage, error) {
var peerPublicKey32 [keySize]byte encryptedMessage := EncryptedMessage{}
m := EncryptedMessage{}
// get the peer public key // get the peer public key
peerPublicKey := verificationEngine.PublicKey() peerPublicKey := verificationEngine.PublicKey()
// check the size of the peerPublicKey // check the size of the peerPublicKey
if len(peerPublicKey) != keySize { if len(peerPublicKey) != keySize {
return m, KeyNotValidError return encryptedMessage, KeyNotValidError
} }
// check the peerPublicKey is not empty (all zeros) // check the peerPublicKey is not empty (all zeros)
if bytes.Compare(peerPublicKey[:], emptyKey) == 0 { if bytes.Compare(peerPublicKey[:], emptyKey) == 0 {
return m, KeyNotValidError return encryptedMessage, KeyNotValidError
} }
// verify the copy succeeded
total := copy(peerPublicKey32[:], peerPublicKey[:keySize])
if total != keySize {
return m, KeyNotValidError
}
// assign the public key to peerPublicKey struct field
engine.peerPublicKey = peerPublicKey32
// derive nonce // derive nonce
nonce, err := deriveNonce(engine.nonceKey, engine.salt, engine.context) nonce, err := deriveNonce(engine.nonceKey, engine.salt, engine.context, engine.fetchAndIncrement())
if err != nil { if err != nil {
return m, err return encryptedMessage, err
} }
m.nonce = nonce // set the nonce to the encrypted message
encryptedMessage.nonce = nonce
// precompute the shared key, if it was not already // calculate the hash of the peer public key
if !engine.preSharedInitialized { sha224String := fmt.Sprintf("%x", sha256.Sum224(peerPublicKey[:]))
box.Precompute(&engine.sharedKey, &engine.peerPublicKey, &engine.privateKey)
engine.preSharedInitialized = true // lock the mutex
engine.mutex.Lock()
// check if the pre sgared key is already present in the map
if preSharedKey, ok := engine.preSharedKeysMap[sha224String]; ok { // means the key is there
// unlock the mutex
engine.mutex.Unlock()
// encrypt with the pre-computed key
encryptedData := box.SealAfterPrecomputation(nil, msg.toBytes(), &nonce, &preSharedKey)
// assign the encrypted data to the message
encryptedMessage.data = encryptedData
} else { // means the key is not there
// generate the key
// init the buffer
preSharedKey = [keySize]byte{}
// precompute the share key
box.Precompute(&preSharedKey, &peerPublicKey, &engine.privateKey)
// assign it to the map
engine.preSharedKeysMap[sha224String] = preSharedKey
// unlock the mutex once the map has the sharedKey set
engine.mutex.Unlock()
// encrypt with the pre-computed key
encryptedData := box.SealAfterPrecomputation(nil, msg.toBytes(), &nonce, &preSharedKey)
// assign the encrypted data to the message
encryptedMessage.data = encryptedData
} }
encryptedData := box.Seal(nil, msg.toBytes(), &m.nonce, &engine.peerPublicKey, &engine.privateKey)
// assign the encrypted data to the message
m.data = encryptedData
// calculate the size of the message // calculate the size of the message
m.length = uint64(len(m.data) + len(m.nonce)) encryptedMessage.length = uint64(len(encryptedMessage.data) + len(encryptedMessage.nonce) + 8)
return m, nil return encryptedMessage, nil
} }
@ -431,36 +474,36 @@ func (engine *CryptoEngine) DecryptWithPublicKey(encryptedBytes []byte, verifica
return nil, KeyNotValidError return nil, KeyNotValidError
} }
// copy the key // calculate the hash of the peer public key
if total := copy(engine.peerPublicKey[:], peerPublicKey[:keySize]); total != keySize { sha224String := fmt.Sprintf("%x", sha256.Sum224(peerPublicKey[:]))
return nil, KeyNotValidError
}
// Decrypt with the pre-initialized key // lock the mutex
if engine.preSharedInitialized { engine.mutex.Lock()
messageBytes, err := decryptWithPreShared(engine, encryptedMessage)
// check if the pre sgared key is already present in the map
if preSharedKey, ok := engine.preSharedKeysMap[sha224String]; ok { // means the key is there
// unlock the mutex
engine.mutex.Unlock()
messageBytes, err := decryptWithPreShared(preSharedKey, encryptedMessage)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return messageFromBytes(messageBytes)
} else {
// otherwise decrypt with the standard box open function
messageBytes, valid := box.Open(nil, encryptedMessage.data, &encryptedMessage.nonce, &peerPublicKey, &engine.privateKey)
if !valid {
return nil, MessageDecryptionError
}
return messageFromBytes(messageBytes) return messageFromBytes(messageBytes)
} }
// pre-compute the key and decrypt
box.Precompute(&engine.sharedKey, &engine.peerPublicKey, &engine.privateKey)
engine.preSharedInitialized = true
messageBytes, err := decryptWithPreShared(engine, encryptedMessage)
if err != nil {
return nil, err
}
return messageFromBytes(messageBytes)
} }
func decryptWithPreShared(engine *CryptoEngine, m EncryptedMessage) ([]byte, error) { func decryptWithPreShared(preSharedKey [keySize]byte, m EncryptedMessage) ([]byte, error) {
if decryptedMessage, valid := box.OpenAfterPrecomputation(nil, m.data, &m.nonce, &engine.sharedKey); !valid { if decryptedMessage, valid := box.OpenAfterPrecomputation(nil, m.data, &m.nonce, &preSharedKey); !valid {
return nil, MessageDecryptionError return nil, MessageDecryptionError
} else { } else {
return decryptedMessage, nil return decryptedMessage, nil

View File

@ -1,213 +0,0 @@
package cryptoengine
import (
"bytes"
"io/ioutil"
"strings"
"testing"
)
func TestSecretKeyEncryption(t *testing.T) {
message, err := NewMessage("The quick brown fox jumps over the lazy dog", 0)
if err != nil {
t.Fatal(err)
}
enginePeer, err := InitCryptoEngine("Sec51")
if err != nil {
cleanUp()
t.Fatal(err)
}
engine, err := InitCryptoEngine("Sec51")
if err != nil {
cleanUp()
t.Fatal(err)
}
encryptedMessage, err := engine.NewEncryptedMessage(message)
if err != nil {
cleanUp()
t.Fatal(err)
}
messageBytes, err := encryptedMessage.ToBytes()
if err != nil {
cleanUp()
t.Fatal(err)
}
// temporary write the corpus for fuzzing
// writeFile("corpus/4", messageBytes)
// simulate writing to network
var buffer bytes.Buffer
buffer.Write(messageBytes)
// read the bytes back
storedData, err := ioutil.ReadAll(&buffer)
if err != nil {
cleanUp()
t.Fatal(err)
}
// parse the bytes
storedMessage, err := encryptedMessageFromBytes(storedData)
if err != nil {
cleanUp()
t.Fatal(err)
}
// check the encrypted message data if it matches
if storedMessage.length != encryptedMessage.length {
t.Error("Encrypted Message length mismacth")
}
if bytes.Compare(storedMessage.nonce[:], encryptedMessage.nonce[:]) != 0 {
t.Error("Encrypted Message nonce mismacth")
}
if bytes.Compare(storedMessage.data[:], encryptedMessage.data[:]) != 0 {
t.Error("Encrypted Message data mismacth")
}
decrypted, err := enginePeer.Decrypt(messageBytes)
if err != nil {
cleanUp()
t.Fatal(err)
}
if decrypted.Type != message.Type {
cleanUp()
t.Fatal("Secret key encryption/decryption broken")
}
if decrypted.Version != message.Version {
cleanUp()
t.Fatal("Secret key encryption/decryption broken")
}
if decrypted.Text != message.Text {
cleanUp()
t.Fatal("Secret key encryption/decryption broken")
}
}
func TestPublicKeyEncryption(t *testing.T) {
message, err := NewMessage("The quick brown fox jumps over the lazy dog", 0)
if err != nil {
t.Fatal(err)
}
firstEngine, err := InitCryptoEngine("Sec51Peer1")
if err != nil {
cleanUp()
t.Fatal(err)
}
// test the verification engine
firstVerificationEngine, err := NewVerificationEngine("Sec51Peer1")
if err != nil {
cleanUp()
t.Fatal(err)
}
secondEngine, err := InitCryptoEngine("Sec51Peer2")
if err != nil {
cleanUp()
t.Fatal(err)
}
// test the verification engine
secondVerificationEngine, err := NewVerificationEngineWithKey(secondEngine.PublicKey())
if err != nil {
cleanUp()
t.Fatal(err)
}
encryptedMessage, err := firstEngine.NewEncryptedMessageWithPubKey(message, secondVerificationEngine)
if err != nil {
cleanUp()
t.Fatal(err)
}
messageBytes, err := encryptedMessage.ToBytes()
if err != nil {
cleanUp()
t.Fatal(err)
}
// temporary write the corpus for fuzzing
// writeFile("corpus/5", messageBytes)
// simulate writing to network
var buffer bytes.Buffer
buffer.Write(messageBytes)
// read the bytes back
storedData, err := ioutil.ReadAll(&buffer)
if err != nil {
cleanUp()
t.Fatal(err)
}
// parse the bytes
storedMessage, err := encryptedMessageFromBytes(storedData)
if err != nil {
cleanUp()
t.Fatal(err)
}
// check the encrypted message data if it matches
if storedMessage.length != encryptedMessage.length {
t.Error("Encrypted Message length mismacth")
}
if bytes.Compare(storedMessage.nonce[:], encryptedMessage.nonce[:]) != 0 {
t.Error("Encrypted Message nonce mismacth")
}
if bytes.Compare(storedMessage.data[:], encryptedMessage.data[:]) != 0 {
t.Error("Encrypted Message data mismacth")
}
decrypted, err := secondEngine.DecryptWithPublicKey(messageBytes, firstVerificationEngine)
if err != nil {
cleanUp()
t.Fatal(err)
}
if decrypted.Version != message.Version {
cleanUp()
t.Fatal("Public key encryption/decryption broken")
}
if decrypted.Type != message.Type {
cleanUp()
t.Fatal("Public key encryption/decryption broken")
}
if decrypted.Text != message.Text {
cleanUp()
t.Fatal("Public key encryption/decryption broken")
}
}
func TestSanitization(t *testing.T) {
id := "S E C 51"
sanitized := sanitizeIdentifier(id)
if strings.Contains(sanitized, " ") {
t.Error("The sanitization function does not remove spaces")
}
if strings.Contains(sanitized, "\t") {
t.Error("The sanitization function does not remove tabs")
}
}
func cleanUp() {
//removeFolder(keyPath)
}

View File

@ -1,111 +0,0 @@
package cryptoengine
import (
"bytes"
"fmt"
"os"
"testing"
)
func TestFileExists(t *testing.T) {
// create key base folder
if err := createBaseKeyFolder(testKeyPath); err != nil {
t.Error(err)
}
if !fileExists(testKeyPath) {
t.Fatalf("%s should have been created", testKeyPath)
}
}
func TestFileUtils(t *testing.T) {
// create key base folder
if err := createBaseKeyFolder(testKeyPath); err != nil {
t.Error(err)
}
filename := "temp.txt"
dataString := "TEST DATA"
data := []byte(dataString)
// write a simple file
err := writeFile(filename, data)
if err != nil {
t.Error(err)
}
// rewrite the same file, it should trigger an error
err = writeFile(filename, data)
if err != os.ErrExist {
t.Errorf("The expected error is: os.ErrExist, instead we've got: %s\n", err)
}
// check if the file exists, it should
if !fileExists(filename) {
t.Fatal("The file should exist!")
}
// read the file back
storedData, err := readFile(filename)
if err != nil {
t.Fatal(err)
}
// read the data back
storedString := string(storedData)
if storedString != dataString {
t.Error("The data in the file is corrupted")
}
// delete the file
if err := deleteFile(filename); err != nil {
t.Fatal(err)
}
// delete the keys folder
if err := removeFolder(testKeyPath); err != nil {
t.Fatal(err)
}
}
func TestKeyFileUtils(t *testing.T) {
// create key base folder
if err := createBaseKeyFolder(testKeyPath); err != nil {
t.Error(err)
}
var key [keySize]byte
var err error
filename := "test_secret.key"
key, err = generateSecretKey()
if err != nil {
t.Fatal(err)
}
if err := writeKey(filename, testKeysFolderPrefixFormat, key[:]); err != nil {
t.Fatal(err)
}
storedKey, err := readKey(filename, testKeysFolderPrefixFormat)
if err != nil {
t.Fatal(err)
}
if bytes.Compare(key[:], storedKey[:]) != 0 {
t.Fatal("The generated random key and the stored one, do not match")
}
if err := deleteFile(fmt.Sprintf(testKeysFolderPrefixFormat, filename)); err != nil {
t.Error(err)
}
// delete the keys folder
if err := removeFolder(testKeyPath); err != nil {
t.Fatal(err)
}
}

View File

@ -10,13 +10,13 @@ import (
// IMPORTANT !!! // IMPORTANT !!!
// If someone changes the hash function, then the salt needs to have the exactly same lenght! // If someone changes the hash function, then the salt needs to have the exactly same lenght!
// So be careful when touching this. // So be careful when touching this.
func deriveNonce(masterKey [keySize]byte, salt [keySize]byte, context string) ([nonceSize]byte, error) { func deriveNonce(masterKey [keySize]byte, salt [keySize]byte, context string, counterValue string) ([nonceSize]byte, error) {
var data24 [nonceSize]byte var data24 [nonceSize]byte
// Underlying hash function to use // Underlying hash function to use
hash := sha256.New hash := sha256.New
// Create the key derivation function // Create the key derivation function
hkdf := hkdf.New(hash, masterKey[:], salt[:], []byte(context)) hkdf := hkdf.New(hash, masterKey[:], salt[:], []byte(context+counterValue))
// Generate the required keys // Generate the required keys
key := make([]byte, nonceSize) key := make([]byte, nonceSize)
n, err := io.ReadFull(hkdf, key) n, err := io.ReadFull(hkdf, key)

View File

@ -51,7 +51,7 @@ func (m message) toBytes() []byte {
versionBytes := smallendian.ToInt(m.Version) versionBytes := smallendian.ToInt(m.Version)
buffer.Write(versionBytes[:]) buffer.Write(versionBytes[:])
// version // type
typeBytes := smallendian.ToInt(m.Type) typeBytes := smallendian.ToInt(m.Type)
buffer.Write(typeBytes[:]) buffer.Write(typeBytes[:])
@ -123,7 +123,7 @@ func messageFromBytes(data []byte) (*message, error) {
version := data[:4] version := data[:4]
typeMsg := data[4:8] typeMsg := data[4:8]
message := data[minimumDataSize:] message := data[8:]
total := copy(versionData[:], version) total := copy(versionData[:], version)
if total != 4 { if total != 4 {
@ -136,14 +136,13 @@ func messageFromBytes(data []byte) (*message, error) {
} }
m.Version = smallendian.FromInt(versionData) m.Version = smallendian.FromInt(versionData)
m.Type = smallendian.FromInt(versionData) m.Type = smallendian.FromInt(typeData)
m.Text = string(message) m.Text = string(message)
return m, err return m, err
} }
// STRUCTURE // STRUCTURE
// 8 => |SIZE| // 8 => |SIZE|
// 1 => |VERSION|
// 24 => |NONCE| // 24 => |NONCE|
// N => |DATA| // N => |DATA|
// |size| => 8 bytes (uint64 total message length) // |size| => 8 bytes (uint64 total message length)

View File

@ -6,6 +6,8 @@ import (
"fmt" "fmt"
) )
// The verification engine links two peers basically.
// It holds the public key and the remote peer public key and the pre-shared key
type VerificationEngine struct { type VerificationEngine struct {
publicKey [keySize]byte // the peer public key publicKey [keySize]byte // the peer public key
signingPublicKey [keySize]byte // the peer public signing key => this is not implemented yet, because go does not support Ed25519 signatures yet signingPublicKey [keySize]byte // the peer public signing key => this is not implemented yet, because go does not support Ed25519 signatures yet
@ -22,7 +24,7 @@ func NewVerificationEngine(context string) (VerificationEngine, error) {
} }
// try to load the public key and if it succeed, then return both the keys // try to load the public key and if it succeed, then return both the keys
publicFile := fmt.Sprintf(publicKeySuffixFormat, context) publicFile := fmt.Sprintf(publicKeySuffixFormat, sanitizeIdentifier(context))
// if the key exists // if the key exists
if keyFileExists(publicFile) { if keyFileExists(publicFile) {
// try to read it // try to read it

27
Godeps/_workspace/src/github.com/sec51/rsc/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,149 @@
// +build ignore
package main
import "fmt"
// tables from qrencode-3.1.1/qrspec.c
var capacity = [41]struct {
width int
words int
remainder int
ec [4]int
}{
{0, 0, 0, [4]int{0, 0, 0, 0}},
{21, 26, 0, [4]int{7, 10, 13, 17}}, // 1
{25, 44, 7, [4]int{10, 16, 22, 28}},
{29, 70, 7, [4]int{15, 26, 36, 44}},
{33, 100, 7, [4]int{20, 36, 52, 64}},
{37, 134, 7, [4]int{26, 48, 72, 88}}, // 5
{41, 172, 7, [4]int{36, 64, 96, 112}},
{45, 196, 0, [4]int{40, 72, 108, 130}},
{49, 242, 0, [4]int{48, 88, 132, 156}},
{53, 292, 0, [4]int{60, 110, 160, 192}},
{57, 346, 0, [4]int{72, 130, 192, 224}}, //10
{61, 404, 0, [4]int{80, 150, 224, 264}},
{65, 466, 0, [4]int{96, 176, 260, 308}},
{69, 532, 0, [4]int{104, 198, 288, 352}},
{73, 581, 3, [4]int{120, 216, 320, 384}},
{77, 655, 3, [4]int{132, 240, 360, 432}}, //15
{81, 733, 3, [4]int{144, 280, 408, 480}},
{85, 815, 3, [4]int{168, 308, 448, 532}},
{89, 901, 3, [4]int{180, 338, 504, 588}},
{93, 991, 3, [4]int{196, 364, 546, 650}},
{97, 1085, 3, [4]int{224, 416, 600, 700}}, //20
{101, 1156, 4, [4]int{224, 442, 644, 750}},
{105, 1258, 4, [4]int{252, 476, 690, 816}},
{109, 1364, 4, [4]int{270, 504, 750, 900}},
{113, 1474, 4, [4]int{300, 560, 810, 960}},
{117, 1588, 4, [4]int{312, 588, 870, 1050}}, //25
{121, 1706, 4, [4]int{336, 644, 952, 1110}},
{125, 1828, 4, [4]int{360, 700, 1020, 1200}},
{129, 1921, 3, [4]int{390, 728, 1050, 1260}},
{133, 2051, 3, [4]int{420, 784, 1140, 1350}},
{137, 2185, 3, [4]int{450, 812, 1200, 1440}}, //30
{141, 2323, 3, [4]int{480, 868, 1290, 1530}},
{145, 2465, 3, [4]int{510, 924, 1350, 1620}},
{149, 2611, 3, [4]int{540, 980, 1440, 1710}},
{153, 2761, 3, [4]int{570, 1036, 1530, 1800}},
{157, 2876, 0, [4]int{570, 1064, 1590, 1890}}, //35
{161, 3034, 0, [4]int{600, 1120, 1680, 1980}},
{165, 3196, 0, [4]int{630, 1204, 1770, 2100}},
{169, 3362, 0, [4]int{660, 1260, 1860, 2220}},
{173, 3532, 0, [4]int{720, 1316, 1950, 2310}},
{177, 3706, 0, [4]int{750, 1372, 2040, 2430}}, //40
}
var eccTable = [41][4][2]int{
{{0, 0}, {0, 0}, {0, 0}, {0, 0}},
{{1, 0}, {1, 0}, {1, 0}, {1, 0}}, // 1
{{1, 0}, {1, 0}, {1, 0}, {1, 0}},
{{1, 0}, {1, 0}, {2, 0}, {2, 0}},
{{1, 0}, {2, 0}, {2, 0}, {4, 0}},
{{1, 0}, {2, 0}, {2, 2}, {2, 2}}, // 5
{{2, 0}, {4, 0}, {4, 0}, {4, 0}},
{{2, 0}, {4, 0}, {2, 4}, {4, 1}},
{{2, 0}, {2, 2}, {4, 2}, {4, 2}},
{{2, 0}, {3, 2}, {4, 4}, {4, 4}},
{{2, 2}, {4, 1}, {6, 2}, {6, 2}}, //10
{{4, 0}, {1, 4}, {4, 4}, {3, 8}},
{{2, 2}, {6, 2}, {4, 6}, {7, 4}},
{{4, 0}, {8, 1}, {8, 4}, {12, 4}},
{{3, 1}, {4, 5}, {11, 5}, {11, 5}},
{{5, 1}, {5, 5}, {5, 7}, {11, 7}}, //15
{{5, 1}, {7, 3}, {15, 2}, {3, 13}},
{{1, 5}, {10, 1}, {1, 15}, {2, 17}},
{{5, 1}, {9, 4}, {17, 1}, {2, 19}},
{{3, 4}, {3, 11}, {17, 4}, {9, 16}},
{{3, 5}, {3, 13}, {15, 5}, {15, 10}}, //20
{{4, 4}, {17, 0}, {17, 6}, {19, 6}},
{{2, 7}, {17, 0}, {7, 16}, {34, 0}},
{{4, 5}, {4, 14}, {11, 14}, {16, 14}},
{{6, 4}, {6, 14}, {11, 16}, {30, 2}},
{{8, 4}, {8, 13}, {7, 22}, {22, 13}}, //25
{{10, 2}, {19, 4}, {28, 6}, {33, 4}},
{{8, 4}, {22, 3}, {8, 26}, {12, 28}},
{{3, 10}, {3, 23}, {4, 31}, {11, 31}},
{{7, 7}, {21, 7}, {1, 37}, {19, 26}},
{{5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30
{{13, 3}, {2, 29}, {42, 1}, {23, 28}},
{{17, 0}, {10, 23}, {10, 35}, {19, 35}},
{{17, 1}, {14, 21}, {29, 19}, {11, 46}},
{{13, 6}, {14, 23}, {44, 7}, {59, 1}},
{{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35
{{6, 14}, {6, 34}, {46, 10}, {2, 64}},
{{17, 4}, {29, 14}, {49, 10}, {24, 46}},
{{4, 18}, {13, 32}, {48, 14}, {42, 32}},
{{20, 4}, {40, 7}, {43, 22}, {10, 67}},
{{19, 6}, {18, 31}, {34, 34}, {20, 61}}, //40
}
var align = [41][2]int{
{0, 0},
{0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5
{34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10
{30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15
{26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20
{28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25
{30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30
{30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35
{24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40
}
var versionPattern = [41]int{
0,
0, 0, 0, 0, 0, 0,
0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
0x27541, 0x28c69,
}
func main() {
fmt.Printf("\t{},\n")
for i := 1; i <= 40; i++ {
apos := align[i][0] - 2
if apos < 0 {
apos = 100
}
astride := align[i][1] - align[i][0]
if astride < 1 {
astride = 100
}
fmt.Printf("\t{%v, %v, %v, %#x, [4]level{{%v, %v}, {%v, %v}, {%v, %v}, {%v, %v}}}, // %v\n",
apos, astride, capacity[i].words,
versionPattern[i],
eccTable[i][0][0]+eccTable[i][0][1],
float64(capacity[i].ec[0])/float64(eccTable[i][0][0]+eccTable[i][0][1]),
eccTable[i][1][0]+eccTable[i][1][1],
float64(capacity[i].ec[1])/float64(eccTable[i][1][0]+eccTable[i][1][1]),
eccTable[i][2][0]+eccTable[i][2][1],
float64(capacity[i].ec[2])/float64(eccTable[i][2][0]+eccTable[i][2][1]),
eccTable[i][3][0]+eccTable[i][3][1],
float64(capacity[i].ec[3])/float64(eccTable[i][3][0]+eccTable[i][3][1]),
i,
)
}
}

View File

@ -0,0 +1,815 @@
// Copyright 2011 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 coding implements low-level QR coding details.
package coding
import (
"fmt"
"strconv"
"strings"
"code.google.com/p/rsc/gf256"
)
// Field is the field for QR error correction.
var Field = gf256.NewField(0x11d, 2)
// A Version represents a QR version.
// The version specifies the size of the QR code:
// a QR code with version v has 4v+17 pixels on a side.
// Versions number from 1 to 40: the larger the version,
// the more information the code can store.
type Version int
const MinVersion = 1
const MaxVersion = 40
func (v Version) String() string {
return strconv.Itoa(int(v))
}
func (v Version) sizeClass() int {
if v <= 9 {
return 0
}
if v <= 26 {
return 1
}
return 2
}
// DataBytes returns the number of data bytes that can be
// stored in a QR code with the given version and level.
func (v Version) DataBytes(l Level) int {
vt := &vtab[v]
lev := &vt.level[l]
return vt.bytes - lev.nblock*lev.check
}
// Encoding implements a QR data encoding scheme.
// The implementations--Numeric, Alphanumeric, and String--specify
// the character set and the mapping from UTF-8 to code bits.
// The more restrictive the mode, the fewer code bits are needed.
type Encoding interface {
Check() error
Bits(v Version) int
Encode(b *Bits, v Version)
}
type Bits struct {
b []byte
nbit int
}
func (b *Bits) Reset() {
b.b = b.b[:0]
b.nbit = 0
}
func (b *Bits) Bits() int {
return b.nbit
}
func (b *Bits) Bytes() []byte {
if b.nbit%8 != 0 {
panic("fractional byte")
}
return b.b
}
func (b *Bits) Append(p []byte) {
if b.nbit%8 != 0 {
panic("fractional byte")
}
b.b = append(b.b, p...)
b.nbit += 8 * len(p)
}
func (b *Bits) Write(v uint, nbit int) {
for nbit > 0 {
n := nbit
if n > 8 {
n = 8
}
if b.nbit%8 == 0 {
b.b = append(b.b, 0)
} else {
m := -b.nbit & 7
if n > m {
n = m
}
}
b.nbit += n
sh := uint(nbit - n)
b.b[len(b.b)-1] |= uint8(v >> sh << uint(-b.nbit&7))
v -= v >> sh << sh
nbit -= n
}
}
// Num is the encoding for numeric data.
// The only valid characters are the decimal digits 0 through 9.
type Num string
func (s Num) String() string {
return fmt.Sprintf("Num(%#q)", string(s))
}
func (s Num) Check() error {
for _, c := range s {
if c < '0' || '9' < c {
return fmt.Errorf("non-numeric string %#q", string(s))
}
}
return nil
}
var numLen = [3]int{10, 12, 14}
func (s Num) Bits(v Version) int {
return 4 + numLen[v.sizeClass()] + (10*len(s)+2)/3
}
func (s Num) Encode(b *Bits, v Version) {
b.Write(1, 4)
b.Write(uint(len(s)), numLen[v.sizeClass()])
var i int
for i = 0; i+3 <= len(s); i += 3 {
w := uint(s[i]-'0')*100 + uint(s[i+1]-'0')*10 + uint(s[i+2]-'0')
b.Write(w, 10)
}
switch len(s) - i {
case 1:
w := uint(s[i] - '0')
b.Write(w, 4)
case 2:
w := uint(s[i]-'0')*10 + uint(s[i+1]-'0')
b.Write(w, 7)
}
}
// Alpha is the encoding for alphanumeric data.
// The valid characters are 0-9A-Z$%*+-./: and space.
type Alpha string
const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
func (s Alpha) String() string {
return fmt.Sprintf("Alpha(%#q)", string(s))
}
func (s Alpha) Check() error {
for _, c := range s {
if strings.IndexRune(alphabet, c) < 0 {
return fmt.Errorf("non-alphanumeric string %#q", string(s))
}
}
return nil
}
var alphaLen = [3]int{9, 11, 13}
func (s Alpha) Bits(v Version) int {
return 4 + alphaLen[v.sizeClass()] + (11*len(s)+1)/2
}
func (s Alpha) Encode(b *Bits, v Version) {
b.Write(2, 4)
b.Write(uint(len(s)), alphaLen[v.sizeClass()])
var i int
for i = 0; i+2 <= len(s); i += 2 {
w := uint(strings.IndexRune(alphabet, rune(s[i])))*45 +
uint(strings.IndexRune(alphabet, rune(s[i+1])))
b.Write(w, 11)
}
if i < len(s) {
w := uint(strings.IndexRune(alphabet, rune(s[i])))
b.Write(w, 6)
}
}
// String is the encoding for 8-bit data. All bytes are valid.
type String string
func (s String) String() string {
return fmt.Sprintf("String(%#q)", string(s))
}
func (s String) Check() error {
return nil
}
var stringLen = [3]int{8, 16, 16}
func (s String) Bits(v Version) int {
return 4 + stringLen[v.sizeClass()] + 8*len(s)
}
func (s String) Encode(b *Bits, v Version) {
b.Write(4, 4)
b.Write(uint(len(s)), stringLen[v.sizeClass()])
for i := 0; i < len(s); i++ {
b.Write(uint(s[i]), 8)
}
}
// A Pixel describes a single pixel in a QR code.
type Pixel uint32
const (
Black Pixel = 1 << iota
Invert
)
func (p Pixel) Offset() uint {
return uint(p >> 6)
}
func OffsetPixel(o uint) Pixel {
return Pixel(o << 6)
}
func (r PixelRole) Pixel() Pixel {
return Pixel(r << 2)
}
func (p Pixel) Role() PixelRole {
return PixelRole(p>>2) & 15
}
func (p Pixel) String() string {
s := p.Role().String()
if p&Black != 0 {
s += "+black"
}
if p&Invert != 0 {
s += "+invert"
}
s += "+" + strconv.FormatUint(uint64(p.Offset()), 10)
return s
}
// A PixelRole describes the role of a QR pixel.
type PixelRole uint32
const (
_ PixelRole = iota
Position // position squares (large)
Alignment // alignment squares (small)
Timing // timing strip between position squares
Format // format metadata
PVersion // version pattern
Unused // unused pixel
Data // data bit
Check // error correction check bit
Extra
)
var roles = []string{
"",
"position",
"alignment",
"timing",
"format",
"pversion",
"unused",
"data",
"check",
"extra",
}
func (r PixelRole) String() string {
if Position <= r && r <= Check {
return roles[r]
}
return strconv.Itoa(int(r))
}
// A Level represents a QR error correction level.
// From least to most tolerant of errors, they are L, M, Q, H.
type Level int
const (
L Level = iota
M
Q
H
)
func (l Level) String() string {
if L <= l && l <= H {
return "LMQH"[l : l+1]
}
return strconv.Itoa(int(l))
}
// A Code is a square pixel grid.
type Code struct {
Bitmap []byte // 1 is black, 0 is white
Size int // number of pixels on a side
Stride int // number of bytes per row
}
func (c *Code) Black(x, y int) bool {
return 0 <= x && x < c.Size && 0 <= y && y < c.Size &&
c.Bitmap[y*c.Stride+x/8]&(1<<uint(7-x&7)) != 0
}
// A Mask describes a mask that is applied to the QR
// code to avoid QR artifacts being interpreted as
// alignment and timing patterns (such as the squares
// in the corners). Valid masks are integers from 0 to 7.
type Mask int
// http://www.swetake.com/qr/qr5_en.html
var mfunc = []func(int, int) bool{
func(i, j int) bool { return (i+j)%2 == 0 },
func(i, j int) bool { return i%2 == 0 },
func(i, j int) bool { return j%3 == 0 },
func(i, j int) bool { return (i+j)%3 == 0 },
func(i, j int) bool { return (i/2+j/3)%2 == 0 },
func(i, j int) bool { return i*j%2+i*j%3 == 0 },
func(i, j int) bool { return (i*j%2+i*j%3)%2 == 0 },
func(i, j int) bool { return (i*j%3+(i+j)%2)%2 == 0 },
}
func (m Mask) Invert(y, x int) bool {
if m < 0 {
return false
}
return mfunc[m](y, x)
}
// A Plan describes how to construct a QR code
// with a specific version, level, and mask.
type Plan struct {
Version Version
Level Level
Mask Mask
DataBytes int // number of data bytes
CheckBytes int // number of error correcting (checksum) bytes
Blocks int // number of data blocks
Pixel [][]Pixel // pixel map
}
// NewPlan returns a Plan for a QR code with the given
// version, level, and mask.
func NewPlan(version Version, level Level, mask Mask) (*Plan, error) {
p, err := vplan(version)
if err != nil {
return nil, err
}
if err := fplan(level, mask, p); err != nil {
return nil, err
}
if err := lplan(version, level, p); err != nil {
return nil, err
}
if err := mplan(mask, p); err != nil {
return nil, err
}
return p, nil
}
func (b *Bits) Pad(n int) {
if n < 0 {
panic("qr: invalid pad size")
}
if n <= 4 {
b.Write(0, n)
} else {
b.Write(0, 4)
n -= 4
n -= -b.Bits() & 7
b.Write(0, -b.Bits()&7)
pad := n / 8
for i := 0; i < pad; i += 2 {
b.Write(0xec, 8)
if i+1 >= pad {
break
}
b.Write(0x11, 8)
}
}
}
func (b *Bits) AddCheckBytes(v Version, l Level) {
nd := v.DataBytes(l)
if b.nbit < nd*8 {
b.Pad(nd*8 - b.nbit)
}
if b.nbit != nd*8 {
panic("qr: too much data")
}
dat := b.Bytes()
vt := &vtab[v]
lev := &vt.level[l]
db := nd / lev.nblock
extra := nd % lev.nblock
chk := make([]byte, lev.check)
rs := gf256.NewRSEncoder(Field, lev.check)
for i := 0; i < lev.nblock; i++ {
if i == lev.nblock-extra {
db++
}
rs.ECC(dat[:db], chk)
b.Append(chk)
dat = dat[db:]
}
if len(b.Bytes()) != vt.bytes {
panic("qr: internal error")
}
}
func (p *Plan) Encode(text ...Encoding) (*Code, error) {
var b Bits
for _, t := range text {
if err := t.Check(); err != nil {
return nil, err
}
t.Encode(&b, p.Version)
}
if b.Bits() > p.DataBytes*8 {
return nil, fmt.Errorf("cannot encode %d bits into %d-bit code", b.Bits(), p.DataBytes*8)
}
b.AddCheckBytes(p.Version, p.Level)
bytes := b.Bytes()
// Now we have the checksum bytes and the data bytes.
// Construct the actual code.
c := &Code{Size: len(p.Pixel), Stride: (len(p.Pixel) + 7) &^ 7}
c.Bitmap = make([]byte, c.Stride*c.Size)
crow := c.Bitmap
for _, row := range p.Pixel {
for x, pix := range row {
switch pix.Role() {
case Data, Check:
o := pix.Offset()
if bytes[o/8]&(1<<uint(7-o&7)) != 0 {
pix ^= Black
}
}
if pix&Black != 0 {
crow[x/8] |= 1 << uint(7-x&7)
}
}
crow = crow[c.Stride:]
}
return c, nil
}
// A version describes metadata associated with a version.
type version struct {
apos int
astride int
bytes int
pattern int
level [4]level
}
type level struct {
nblock int
check int
}
var vtab = []version{
{},
{100, 100, 26, 0x0, [4]level{{1, 7}, {1, 10}, {1, 13}, {1, 17}}}, // 1
{16, 100, 44, 0x0, [4]level{{1, 10}, {1, 16}, {1, 22}, {1, 28}}}, // 2
{20, 100, 70, 0x0, [4]level{{1, 15}, {1, 26}, {2, 18}, {2, 22}}}, // 3
{24, 100, 100, 0x0, [4]level{{1, 20}, {2, 18}, {2, 26}, {4, 16}}}, // 4
{28, 100, 134, 0x0, [4]level{{1, 26}, {2, 24}, {4, 18}, {4, 22}}}, // 5
{32, 100, 172, 0x0, [4]level{{2, 18}, {4, 16}, {4, 24}, {4, 28}}}, // 6
{20, 16, 196, 0x7c94, [4]level{{2, 20}, {4, 18}, {6, 18}, {5, 26}}}, // 7
{22, 18, 242, 0x85bc, [4]level{{2, 24}, {4, 22}, {6, 22}, {6, 26}}}, // 8
{24, 20, 292, 0x9a99, [4]level{{2, 30}, {5, 22}, {8, 20}, {8, 24}}}, // 9
{26, 22, 346, 0xa4d3, [4]level{{4, 18}, {5, 26}, {8, 24}, {8, 28}}}, // 10
{28, 24, 404, 0xbbf6, [4]level{{4, 20}, {5, 30}, {8, 28}, {11, 24}}}, // 11
{30, 26, 466, 0xc762, [4]level{{4, 24}, {8, 22}, {10, 26}, {11, 28}}}, // 12
{32, 28, 532, 0xd847, [4]level{{4, 26}, {9, 22}, {12, 24}, {16, 22}}}, // 13
{24, 20, 581, 0xe60d, [4]level{{4, 30}, {9, 24}, {16, 20}, {16, 24}}}, // 14
{24, 22, 655, 0xf928, [4]level{{6, 22}, {10, 24}, {12, 30}, {18, 24}}}, // 15
{24, 24, 733, 0x10b78, [4]level{{6, 24}, {10, 28}, {17, 24}, {16, 30}}}, // 16
{28, 24, 815, 0x1145d, [4]level{{6, 28}, {11, 28}, {16, 28}, {19, 28}}}, // 17
{28, 26, 901, 0x12a17, [4]level{{6, 30}, {13, 26}, {18, 28}, {21, 28}}}, // 18
{28, 28, 991, 0x13532, [4]level{{7, 28}, {14, 26}, {21, 26}, {25, 26}}}, // 19
{32, 28, 1085, 0x149a6, [4]level{{8, 28}, {16, 26}, {20, 30}, {25, 28}}}, // 20
{26, 22, 1156, 0x15683, [4]level{{8, 28}, {17, 26}, {23, 28}, {25, 30}}}, // 21
{24, 24, 1258, 0x168c9, [4]level{{9, 28}, {17, 28}, {23, 30}, {34, 24}}}, // 22
{28, 24, 1364, 0x177ec, [4]level{{9, 30}, {18, 28}, {25, 30}, {30, 30}}}, // 23
{26, 26, 1474, 0x18ec4, [4]level{{10, 30}, {20, 28}, {27, 30}, {32, 30}}}, // 24
{30, 26, 1588, 0x191e1, [4]level{{12, 26}, {21, 28}, {29, 30}, {35, 30}}}, // 25
{28, 28, 1706, 0x1afab, [4]level{{12, 28}, {23, 28}, {34, 28}, {37, 30}}}, // 26
{32, 28, 1828, 0x1b08e, [4]level{{12, 30}, {25, 28}, {34, 30}, {40, 30}}}, // 27
{24, 24, 1921, 0x1cc1a, [4]level{{13, 30}, {26, 28}, {35, 30}, {42, 30}}}, // 28
{28, 24, 2051, 0x1d33f, [4]level{{14, 30}, {28, 28}, {38, 30}, {45, 30}}}, // 29
{24, 26, 2185, 0x1ed75, [4]level{{15, 30}, {29, 28}, {40, 30}, {48, 30}}}, // 30
{28, 26, 2323, 0x1f250, [4]level{{16, 30}, {31, 28}, {43, 30}, {51, 30}}}, // 31
{32, 26, 2465, 0x209d5, [4]level{{17, 30}, {33, 28}, {45, 30}, {54, 30}}}, // 32
{28, 28, 2611, 0x216f0, [4]level{{18, 30}, {35, 28}, {48, 30}, {57, 30}}}, // 33
{32, 28, 2761, 0x228ba, [4]level{{19, 30}, {37, 28}, {51, 30}, {60, 30}}}, // 34
{28, 24, 2876, 0x2379f, [4]level{{19, 30}, {38, 28}, {53, 30}, {63, 30}}}, // 35
{22, 26, 3034, 0x24b0b, [4]level{{20, 30}, {40, 28}, {56, 30}, {66, 30}}}, // 36
{26, 26, 3196, 0x2542e, [4]level{{21, 30}, {43, 28}, {59, 30}, {70, 30}}}, // 37
{30, 26, 3362, 0x26a64, [4]level{{22, 30}, {45, 28}, {62, 30}, {74, 30}}}, // 38
{24, 28, 3532, 0x27541, [4]level{{24, 30}, {47, 28}, {65, 30}, {77, 30}}}, // 39
{28, 28, 3706, 0x28c69, [4]level{{25, 30}, {49, 28}, {68, 30}, {81, 30}}}, // 40
}
func grid(siz int) [][]Pixel {
m := make([][]Pixel, siz)
pix := make([]Pixel, siz*siz)
for i := range m {
m[i], pix = pix[:siz], pix[siz:]
}
return m
}
// vplan creates a Plan for the given version.
func vplan(v Version) (*Plan, error) {
p := &Plan{Version: v}
if v < 1 || v > 40 {
return nil, fmt.Errorf("invalid QR version %d", int(v))
}
siz := 17 + int(v)*4
m := grid(siz)
p.Pixel = m
// Timing markers (overwritten by boxes).
const ti = 6 // timing is in row/column 6 (counting from 0)
for i := range m {
p := Timing.Pixel()
if i&1 == 0 {
p |= Black
}
m[i][ti] = p
m[ti][i] = p
}
// Position boxes.
posBox(m, 0, 0)
posBox(m, siz-7, 0)
posBox(m, 0, siz-7)
// Alignment boxes.
info := &vtab[v]
for x := 4; x+5 < siz; {
for y := 4; y+5 < siz; {
// don't overwrite timing markers
if (x < 7 && y < 7) || (x < 7 && y+5 >= siz-7) || (x+5 >= siz-7 && y < 7) {
} else {
alignBox(m, x, y)
}
if y == 4 {
y = info.apos
} else {
y += info.astride
}
}
if x == 4 {
x = info.apos
} else {
x += info.astride
}
}
// Version pattern.
pat := vtab[v].pattern
if pat != 0 {
v := pat
for x := 0; x < 6; x++ {
for y := 0; y < 3; y++ {
p := PVersion.Pixel()
if v&1 != 0 {
p |= Black
}
m[siz-11+y][x] = p
m[x][siz-11+y] = p
v >>= 1
}
}
}
// One lonely black pixel
m[siz-8][8] = Unused.Pixel() | Black
return p, nil
}
// fplan adds the format pixels
func fplan(l Level, m Mask, p *Plan) error {
// Format pixels.
fb := uint32(l^1) << 13 // level: L=01, M=00, Q=11, H=10
fb |= uint32(m) << 10 // mask
const formatPoly = 0x537
rem := fb
for i := 14; i >= 10; i-- {
if rem&(1<<uint(i)) != 0 {
rem ^= formatPoly << uint(i-10)
}
}
fb |= rem
invert := uint32(0x5412)
siz := len(p.Pixel)
for i := uint(0); i < 15; i++ {
pix := Format.Pixel() + OffsetPixel(i)
if (fb>>i)&1 == 1 {
pix |= Black
}
if (invert>>i)&1 == 1 {
pix ^= Invert | Black
}
// top left
switch {
case i < 6:
p.Pixel[i][8] = pix
case i < 8:
p.Pixel[i+1][8] = pix
case i < 9:
p.Pixel[8][7] = pix
default:
p.Pixel[8][14-i] = pix
}
// bottom right
switch {
case i < 8:
p.Pixel[8][siz-1-int(i)] = pix
default:
p.Pixel[siz-1-int(14-i)][8] = pix
}
}
return nil
}
// lplan edits a version-only Plan to add information
// about the error correction levels.
func lplan(v Version, l Level, p *Plan) error {
p.Level = l
nblock := vtab[v].level[l].nblock
ne := vtab[v].level[l].check
nde := (vtab[v].bytes - ne*nblock) / nblock
extra := (vtab[v].bytes - ne*nblock) % nblock
dataBits := (nde*nblock + extra) * 8
checkBits := ne * nblock * 8
p.DataBytes = vtab[v].bytes - ne*nblock
p.CheckBytes = ne * nblock
p.Blocks = nblock
// Make data + checksum pixels.
data := make([]Pixel, dataBits)
for i := range data {
data[i] = Data.Pixel() | OffsetPixel(uint(i))
}
check := make([]Pixel, checkBits)
for i := range check {
check[i] = Check.Pixel() | OffsetPixel(uint(i+dataBits))
}
// Split into blocks.
dataList := make([][]Pixel, nblock)
checkList := make([][]Pixel, nblock)
for i := 0; i < nblock; i++ {
// The last few blocks have an extra data byte (8 pixels).
nd := nde
if i >= nblock-extra {
nd++
}
dataList[i], data = data[0:nd*8], data[nd*8:]
checkList[i], check = check[0:ne*8], check[ne*8:]
}
if len(data) != 0 || len(check) != 0 {
panic("data/check math")
}
// Build up bit sequence, taking first byte of each block,
// then second byte, and so on. Then checksums.
bits := make([]Pixel, dataBits+checkBits)
dst := bits
for i := 0; i < nde+1; i++ {
for _, b := range dataList {
if i*8 < len(b) {
copy(dst, b[i*8:(i+1)*8])
dst = dst[8:]
}
}
}
for i := 0; i < ne; i++ {
for _, b := range checkList {
if i*8 < len(b) {
copy(dst, b[i*8:(i+1)*8])
dst = dst[8:]
}
}
}
if len(dst) != 0 {
panic("dst math")
}
// Sweep up pair of columns,
// then down, assigning to right then left pixel.
// Repeat.
// See Figure 2 of http://www.pclviewer.com/rs2/qrtopology.htm
siz := len(p.Pixel)
rem := make([]Pixel, 7)
for i := range rem {
rem[i] = Extra.Pixel()
}
src := append(bits, rem...)
for x := siz; x > 0; {
for y := siz - 1; y >= 0; y-- {
if p.Pixel[y][x-1].Role() == 0 {
p.Pixel[y][x-1], src = src[0], src[1:]
}
if p.Pixel[y][x-2].Role() == 0 {
p.Pixel[y][x-2], src = src[0], src[1:]
}
}
x -= 2
if x == 7 { // vertical timing strip
x--
}
for y := 0; y < siz; y++ {
if p.Pixel[y][x-1].Role() == 0 {
p.Pixel[y][x-1], src = src[0], src[1:]
}
if p.Pixel[y][x-2].Role() == 0 {
p.Pixel[y][x-2], src = src[0], src[1:]
}
}
x -= 2
}
return nil
}
// mplan edits a version+level-only Plan to add the mask.
func mplan(m Mask, p *Plan) error {
p.Mask = m
for y, row := range p.Pixel {
for x, pix := range row {
if r := pix.Role(); (r == Data || r == Check || r == Extra) && p.Mask.Invert(y, x) {
row[x] ^= Black | Invert
}
}
}
return nil
}
// posBox draws a position (large) box at upper left x, y.
func posBox(m [][]Pixel, x, y int) {
pos := Position.Pixel()
// box
for dy := 0; dy < 7; dy++ {
for dx := 0; dx < 7; dx++ {
p := pos
if dx == 0 || dx == 6 || dy == 0 || dy == 6 || 2 <= dx && dx <= 4 && 2 <= dy && dy <= 4 {
p |= Black
}
m[y+dy][x+dx] = p
}
}
// white border
for dy := -1; dy < 8; dy++ {
if 0 <= y+dy && y+dy < len(m) {
if x > 0 {
m[y+dy][x-1] = pos
}
if x+7 < len(m) {
m[y+dy][x+7] = pos
}
}
}
for dx := -1; dx < 8; dx++ {
if 0 <= x+dx && x+dx < len(m) {
if y > 0 {
m[y-1][x+dx] = pos
}
if y+7 < len(m) {
m[y+7][x+dx] = pos
}
}
}
}
// alignBox draw an alignment (small) box at upper left x, y.
func alignBox(m [][]Pixel, x, y int) {
// box
align := Alignment.Pixel()
for dy := 0; dy < 5; dy++ {
for dx := 0; dx < 5; dx++ {
p := align
if dx == 0 || dx == 4 || dy == 0 || dy == 4 || dx == 2 && dy == 2 {
p |= Black
}
m[y+dy][x+dx] = p
}
}
}

27
Godeps/_workspace/src/golang.org/x/crypto/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

22
Godeps/_workspace/src/golang.org/x/crypto/PATENTS generated vendored Normal file
View File

@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View File

@ -1,29 +0,0 @@
// Copyright 2012 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 curve25519
import (
"fmt"
"testing"
)
const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a"
func TestBaseScalarMult(t *testing.T) {
var a, b [32]byte
in := &a
out := &b
a[0] = 1
for i := 0; i < 200; i++ {
ScalarBaseMult(out, in)
in, out = out, in
}
result := fmt.Sprintf("%x", in[:])
if result != expectedHex {
t.Errorf("incorrect result: got %s, want %s", result, expectedHex)
}
}

View File

@ -4,7 +4,7 @@
// Package curve25519 provides an implementation of scalar multiplication on // Package curve25519 provides an implementation of scalar multiplication on
// the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html // the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html
package curve25519 // import "golang.org/x/crypto/curve25519" package curve25519
// basePoint is the x coordinate of the generator of the curve. // basePoint is the x coordinate of the generator of the curve.
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

View File

@ -1,61 +0,0 @@
// Copyright 2014 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 hkdf_test
import (
"bytes"
"crypto/rand"
"crypto/sha256"
"fmt"
"golang.org/x/crypto/hkdf"
"io"
)
// Usage example that expands one master key into three other cryptographically
// secure keys.
func Example_usage() {
// Underlying hash function to use
hash := sha256.New
// Cryptographically secure master key.
master := []byte{0x00, 0x01, 0x02, 0x03} // i.e. NOT this.
// Non secret salt, optional (can be nil)
// Recommended: hash-length sized random
salt := make([]byte, hash().Size())
n, err := io.ReadFull(rand.Reader, salt)
if n != len(salt) || err != nil {
fmt.Println("error:", err)
return
}
// Non secret context specific info, optional (can be nil).
// Note, independent from the master key.
info := []byte{0x03, 0x14, 0x15, 0x92, 0x65}
// Create the key derivation function
hkdf := hkdf.New(hash, master, salt, info)
// Generate the required keys
keys := make([][]byte, 3)
for i := 0; i < len(keys); i++ {
keys[i] = make([]byte, 24)
n, err := io.ReadFull(hkdf, keys[i])
if n != len(keys[i]) || err != nil {
fmt.Println("error:", err)
return
}
}
// Keys should contain 192 bit random keys
for i := 1; i <= len(keys); i++ {
fmt.Printf("Key #%d: %v\n", i, !bytes.Equal(keys[i-1], make([]byte, 24)))
}
// Output:
// Key #1: true
// Key #2: true
// Key #3: true
}

View File

@ -10,7 +10,7 @@
// strong secret keys. // strong secret keys.
// //
// RFC 5869: https://tools.ietf.org/html/rfc5869 // RFC 5869: https://tools.ietf.org/html/rfc5869
package hkdf // import "golang.org/x/crypto/hkdf" package hkdf
import ( import (
"crypto/hmac" "crypto/hmac"

View File

@ -1,370 +0,0 @@
// Copyright 2014 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 hkdf
import (
"bytes"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"hash"
"io"
"testing"
)
type hkdfTest struct {
hash func() hash.Hash
master []byte
salt []byte
info []byte
out []byte
}
var hkdfTests = []hkdfTest{
// Tests from RFC 5869
{
sha256.New,
[]byte{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
},
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c,
},
[]byte{
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9,
},
[]byte{
0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
0x58, 0x65,
},
},
{
sha256.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
},
[]byte{
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
},
[]byte{
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
},
[]byte{
0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
0x1d, 0x87,
},
},
{
sha256.New,
[]byte{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
},
[]byte{},
[]byte{},
[]byte{
0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
0x96, 0xc8,
},
},
{
sha1.New,
[]byte{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b,
},
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c,
},
[]byte{
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9,
},
[]byte{
0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69,
0x33, 0x06, 0x8b, 0x56, 0xef, 0xa5, 0xad, 0x81,
0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2,
0xc2, 0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3,
0xf8, 0x96,
},
},
{
sha1.New,
[]byte{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
},
[]byte{
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
},
[]byte{
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
},
[]byte{
0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7,
0xc9, 0xf1, 0x2c, 0xd5, 0x91, 0x2a, 0x06, 0xeb,
0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe,
0x8f, 0xa3, 0xf1, 0xa4, 0xe5, 0xad, 0x79, 0xf3,
0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c,
0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed,
0x03, 0x4c, 0x7f, 0x9d, 0xfe, 0xb1, 0x5c, 0x5e,
0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43,
0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52,
0xd3, 0xb4,
},
},
{
sha1.New,
[]byte{
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
},
[]byte{},
[]byte{},
[]byte{
0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61,
0xd1, 0xe5, 0x52, 0x98, 0xda, 0x9d, 0x05, 0x06,
0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0,
0xea, 0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3,
0x49, 0x18,
},
},
{
sha1.New,
[]byte{
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
},
nil,
[]byte{},
[]byte{
0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3,
0x50, 0x0d, 0x63, 0x6a, 0x62, 0xf6, 0x4f, 0x0a,
0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5,
0x67, 0x3a, 0x08, 0x1d, 0x70, 0xcc, 0xe7, 0xac,
0xfc, 0x48,
},
},
}
func TestHKDF(t *testing.T) {
for i, tt := range hkdfTests {
hkdf := New(tt.hash, tt.master, tt.salt, tt.info)
out := make([]byte, len(tt.out))
n, err := io.ReadFull(hkdf, out)
if n != len(tt.out) || err != nil {
t.Errorf("test %d: not enough output bytes: %d.", i, n)
}
if !bytes.Equal(out, tt.out) {
t.Errorf("test %d: incorrect output: have %v, need %v.", i, out, tt.out)
}
}
}
func TestHKDFMultiRead(t *testing.T) {
for i, tt := range hkdfTests {
hkdf := New(tt.hash, tt.master, tt.salt, tt.info)
out := make([]byte, len(tt.out))
for b := 0; b < len(tt.out); b++ {
n, err := io.ReadFull(hkdf, out[b:b+1])
if n != 1 || err != nil {
t.Errorf("test %d.%d: not enough output bytes: have %d, need %d .", i, b, n, len(tt.out))
}
}
if !bytes.Equal(out, tt.out) {
t.Errorf("test %d: incorrect output: have %v, need %v.", i, out, tt.out)
}
}
}
func TestHKDFLimit(t *testing.T) {
hash := sha1.New
master := []byte{0x00, 0x01, 0x02, 0x03}
info := []byte{}
hkdf := New(hash, master, nil, info)
limit := hash().Size() * 255
out := make([]byte, limit)
// The maximum output bytes should be extractable
n, err := io.ReadFull(hkdf, out)
if n != limit || err != nil {
t.Errorf("not enough output bytes: %d, %v.", n, err)
}
// Reading one more should fail
n, err = io.ReadFull(hkdf, make([]byte, 1))
if n > 0 || err == nil {
t.Errorf("key expansion overflowed: n = %d, err = %v", n, err)
}
}
func Benchmark16ByteMD5Single(b *testing.B) {
benchmarkHKDFSingle(md5.New, 16, b)
}
func Benchmark20ByteSHA1Single(b *testing.B) {
benchmarkHKDFSingle(sha1.New, 20, b)
}
func Benchmark32ByteSHA256Single(b *testing.B) {
benchmarkHKDFSingle(sha256.New, 32, b)
}
func Benchmark64ByteSHA512Single(b *testing.B) {
benchmarkHKDFSingle(sha512.New, 64, b)
}
func Benchmark8ByteMD5Stream(b *testing.B) {
benchmarkHKDFStream(md5.New, 8, b)
}
func Benchmark16ByteMD5Stream(b *testing.B) {
benchmarkHKDFStream(md5.New, 16, b)
}
func Benchmark8ByteSHA1Stream(b *testing.B) {
benchmarkHKDFStream(sha1.New, 8, b)
}
func Benchmark20ByteSHA1Stream(b *testing.B) {
benchmarkHKDFStream(sha1.New, 20, b)
}
func Benchmark8ByteSHA256Stream(b *testing.B) {
benchmarkHKDFStream(sha256.New, 8, b)
}
func Benchmark32ByteSHA256Stream(b *testing.B) {
benchmarkHKDFStream(sha256.New, 32, b)
}
func Benchmark8ByteSHA512Stream(b *testing.B) {
benchmarkHKDFStream(sha512.New, 8, b)
}
func Benchmark64ByteSHA512Stream(b *testing.B) {
benchmarkHKDFStream(sha512.New, 64, b)
}
func benchmarkHKDFSingle(hasher func() hash.Hash, block int, b *testing.B) {
master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}
info := []byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27}
out := make([]byte, block)
b.SetBytes(int64(block))
b.ResetTimer()
for i := 0; i < b.N; i++ {
hkdf := New(hasher, master, salt, info)
io.ReadFull(hkdf, out)
}
}
func benchmarkHKDFStream(hasher func() hash.Hash, block int, b *testing.B) {
master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}
info := []byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27}
out := make([]byte, block)
b.SetBytes(int64(block))
b.ResetTimer()
hkdf := New(hasher, master, salt, info)
for i := 0; i < b.N; i++ {
_, err := io.ReadFull(hkdf, out)
if err != nil {
hkdf = New(hasher, master, salt, info)
i--
}
}
}

View File

@ -15,7 +15,7 @@ negligible risk of collision.
This package is interoperable with NaCl: http://nacl.cr.yp.to/box.html. This package is interoperable with NaCl: http://nacl.cr.yp.to/box.html.
*/ */
package box // import "golang.org/x/crypto/nacl/box" package box
import ( import (
"golang.org/x/crypto/curve25519" "golang.org/x/crypto/curve25519"

View File

@ -1,78 +0,0 @@
// Copyright 2012 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 box
import (
"bytes"
"crypto/rand"
"encoding/hex"
"testing"
"golang.org/x/crypto/curve25519"
)
func TestSealOpen(t *testing.T) {
publicKey1, privateKey1, _ := GenerateKey(rand.Reader)
publicKey2, privateKey2, _ := GenerateKey(rand.Reader)
if *privateKey1 == *privateKey2 {
t.Fatalf("private keys are equal!")
}
if *publicKey1 == *publicKey2 {
t.Fatalf("public keys are equal!")
}
message := []byte("test message")
var nonce [24]byte
box := Seal(nil, message, &nonce, publicKey1, privateKey2)
opened, ok := Open(nil, box, &nonce, publicKey2, privateKey1)
if !ok {
t.Fatalf("failed to open box")
}
if !bytes.Equal(opened, message) {
t.Fatalf("got %x, want %x", opened, message)
}
for i := range box {
box[i] ^= 0x40
_, ok := Open(nil, box, &nonce, publicKey2, privateKey1)
if ok {
t.Fatalf("opened box with byte %d corrupted", i)
}
box[i] ^= 0x40
}
}
func TestBox(t *testing.T) {
var privateKey1, privateKey2 [32]byte
for i := range privateKey1[:] {
privateKey1[i] = 1
}
for i := range privateKey2[:] {
privateKey2[i] = 2
}
var publicKey1 [32]byte
curve25519.ScalarBaseMult(&publicKey1, &privateKey1)
var message [64]byte
for i := range message[:] {
message[i] = 3
}
var nonce [24]byte
for i := range nonce[:] {
nonce[i] = 4
}
box := Seal(nil, message[:], &nonce, &publicKey1, &privateKey2)
// expected was generated using the C implementation of NaCl.
expected, _ := hex.DecodeString("78ea30b19d2341ebbdba54180f821eec265cf86312549bea8a37652a8bb94f07b78a73ed1708085e6ddd0e943bbdeb8755079a37eb31d86163ce241164a47629c0539f330b4914cd135b3855bc2a2dfc")
if !bytes.Equal(box, expected) {
t.Fatalf("box didn't match, got\n%x\n, expected\n%x", box, expected)
}
}

View File

@ -15,7 +15,7 @@ negligible risk of collision.
This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html. This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html.
*/ */
package secretbox // import "golang.org/x/crypto/nacl/secretbox" package secretbox
import ( import (
"golang.org/x/crypto/poly1305" "golang.org/x/crypto/poly1305"

View File

@ -1,91 +0,0 @@
// Copyright 2012 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 secretbox
import (
"bytes"
"crypto/rand"
"encoding/hex"
"testing"
)
func TestSealOpen(t *testing.T) {
var key [32]byte
var nonce [24]byte
rand.Reader.Read(key[:])
rand.Reader.Read(nonce[:])
var box, opened []byte
for msgLen := 0; msgLen < 128; msgLen += 17 {
message := make([]byte, msgLen)
rand.Reader.Read(message)
box = Seal(box[:0], message, &nonce, &key)
var ok bool
opened, ok = Open(opened[:0], box, &nonce, &key)
if !ok {
t.Errorf("%d: failed to open box", msgLen)
continue
}
if !bytes.Equal(opened, message) {
t.Errorf("%d: got %x, expected %x", msgLen, opened, message)
continue
}
}
for i := range box {
box[i] ^= 0x20
_, ok := Open(opened[:0], box, &nonce, &key)
if ok {
t.Errorf("box was opened after corrupting byte %d", i)
}
box[i] ^= 0x20
}
}
func TestSecretBox(t *testing.T) {
var key [32]byte
var nonce [24]byte
var message [64]byte
for i := range key[:] {
key[i] = 1
}
for i := range nonce[:] {
nonce[i] = 2
}
for i := range message[:] {
message[i] = 3
}
box := Seal(nil, message[:], &nonce, &key)
// expected was generated using the C implementation of NaCl.
expected, _ := hex.DecodeString("8442bc313f4626f1359e3b50122b6ce6fe66ddfe7d39d14e637eb4fd5b45beadab55198df6ab5368439792a23c87db70acb6156dc5ef957ac04f6276cf6093b84be77ff0849cc33e34b7254d5a8f65ad")
if !bytes.Equal(box, expected) {
t.Fatalf("box didn't match, got\n%x\n, expected\n%x", box, expected)
}
}
func TestAppend(t *testing.T) {
var key [32]byte
var nonce [24]byte
var message [8]byte
out := make([]byte, 4)
box := Seal(out, message[:], &nonce, &key)
if !bytes.Equal(box[:4], out[:4]) {
t.Fatalf("Seal didn't correctly append")
}
out = make([]byte, 4, 100)
box = Seal(out, message[:], &nonce, &key)
if !bytes.Equal(box[:4], out[:4]) {
t.Fatalf("Seal didn't correctly append with sufficient capacity.")
}
}

View File

@ -16,7 +16,7 @@ used with a fixed key in order to generate one-time keys from an nonce.
However, in this package AES isn't used and the one-time key is specified However, in this package AES isn't used and the one-time key is specified
directly. directly.
*/ */
package poly1305 // import "golang.org/x/crypto/poly1305" package poly1305
import "crypto/subtle" import "crypto/subtle"

View File

@ -47,6 +47,16 @@ TEXT poly1305_init_ext_armv6<>(SB),4,$-4
MOVM.IA.W (R13), [R4-R11] MOVM.IA.W (R13), [R4-R11]
RET RET
#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \
MOVBU (offset+0)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+0)(Rdst); \
MOVBU (offset+1)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+1)(Rdst); \
MOVBU (offset+2)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+2)(Rdst); \
MOVBU (offset+3)(Rsrc), Rtmp; \
MOVBU Rtmp, (offset+3)(Rdst)
TEXT poly1305_blocks_armv6<>(SB),4,$-4 TEXT poly1305_blocks_armv6<>(SB),4,$-4
MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13) MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
SUB $128, R13 SUB $128, R13
@ -66,7 +76,19 @@ TEXT poly1305_blocks_armv6<>(SB),4,$-4
CMP $16, R12 CMP $16, R12
BLO poly1305_blocks_armv6_done BLO poly1305_blocks_armv6_done
poly1305_blocks_armv6_mainloop: poly1305_blocks_armv6_mainloop:
WORD $0xe31e0003 // TST R14, #3 not working see issue 5921
BEQ poly1305_blocks_armv6_mainloop_aligned
ADD $48, R13, g
MOVW_UNALIGNED(R14, g, R0, 0)
MOVW_UNALIGNED(R14, g, R0, 4)
MOVW_UNALIGNED(R14, g, R0, 8)
MOVW_UNALIGNED(R14, g, R0, 12)
MOVM.IA (g), [R0-R3]
ADD $16, R14
B poly1305_blocks_armv6_mainloop_loaded
poly1305_blocks_armv6_mainloop_aligned:
MOVM.IA.W (R14), [R0-R3] MOVM.IA.W (R14), [R0-R3]
poly1305_blocks_armv6_mainloop_loaded:
MOVW R0>>26, g MOVW R0>>26, g
MOVW R1>>20, R11 MOVW R1>>20, R11
MOVW R2>>14, R12 MOVW R2>>14, R12
@ -174,6 +196,16 @@ poly1305_blocks_armv6_done:
MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14] MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14]
RET RET
#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \
MOVBU.P 1(Rsrc), Rtmp; \
MOVBU.P Rtmp, 1(Rdst); \
MOVBU.P 1(Rsrc), Rtmp; \
MOVBU.P Rtmp, 1(Rdst)
#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \
MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \
MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp)
TEXT poly1305_finish_ext_armv6<>(SB),4,$-4 TEXT poly1305_finish_ext_armv6<>(SB),4,$-4
MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13) MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
SUB $16, R13, R13 SUB $16, R13, R13
@ -189,16 +221,32 @@ TEXT poly1305_finish_ext_armv6<>(SB),4,$-4
MOVW R0, 4(R13) MOVW R0, 4(R13)
MOVW R0, 8(R13) MOVW R0, 8(R13)
MOVW R0, 12(R13) MOVW R0, 12(R13)
WORD $0xe3110003 // TST R1, #3 not working see issue 5921
BEQ poly1305_finish_ext_armv6_aligned
WORD $0xe3120008 // TST R2, #8 not working see issue 5921 WORD $0xe3120008 // TST R2, #8 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip8 BEQ poly1305_finish_ext_armv6_skip8
MOVM.IA.W (R1), [g-R11] MOVWP_UNALIGNED(R1, R9, g)
MOVM.IA.W [g-R11], (R9) MOVWP_UNALIGNED(R1, R9, g)
poly1305_finish_ext_armv6_skip8: poly1305_finish_ext_armv6_skip8:
WORD $0xe3120004 // TST $4, R2 not working see issue 5921 WORD $0xe3120004 // TST $4, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip4 BEQ poly1305_finish_ext_armv6_skip4
MOVWP_UNALIGNED(R1, R9, g)
poly1305_finish_ext_armv6_skip4:
WORD $0xe3120002 // TST $2, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip2
MOVHUP_UNALIGNED(R1, R9, g)
B poly1305_finish_ext_armv6_skip2
poly1305_finish_ext_armv6_aligned:
WORD $0xe3120008 // TST R2, #8 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip8_aligned
MOVM.IA.W (R1), [g-R11]
MOVM.IA.W [g-R11], (R9)
poly1305_finish_ext_armv6_skip8_aligned:
WORD $0xe3120004 // TST $4, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip4_aligned
MOVW.P 4(R1), g MOVW.P 4(R1), g
MOVW.P g, 4(R9) MOVW.P g, 4(R9)
poly1305_finish_ext_armv6_skip4: poly1305_finish_ext_armv6_skip4_aligned:
WORD $0xe3120002 // TST $2, R2 not working see issue 5921 WORD $0xe3120002 // TST $2, R2 not working see issue 5921
BEQ poly1305_finish_ext_armv6_skip2 BEQ poly1305_finish_ext_armv6_skip2
MOVHU.P 2(R1), g MOVHU.P 2(R1), g

View File

@ -1,74 +0,0 @@
// Copyright 2012 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 poly1305
import (
"bytes"
"testing"
)
var testData = []struct {
in, k, correct []byte
}{
{
[]byte("Hello world!"),
[]byte("this is 32-byte key for Poly1305"),
[]byte{0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2, 0xf0},
},
{
make([]byte, 32),
[]byte("this is 32-byte key for Poly1305"),
[]byte{0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03, 0x07},
},
{
make([]byte, 2007),
[]byte("this is 32-byte key for Poly1305"),
[]byte{0xda, 0x84, 0xbc, 0xab, 0x02, 0x67, 0x6c, 0x38, 0xcd, 0xb0, 0x15, 0x60, 0x42, 0x74, 0xc2, 0xaa},
},
{
make([]byte, 2007),
make([]byte, 32),
make([]byte, 16),
},
}
func TestSum(t *testing.T) {
var out [16]byte
var key [32]byte
for i, v := range testData {
copy(key[:], v.k)
Sum(&out, v.in, &key)
if !bytes.Equal(out[:], v.correct) {
t.Errorf("%d: expected %x, got %x", i, v.correct, out[:])
}
}
}
func Benchmark1K(b *testing.B) {
b.StopTimer()
var out [16]byte
var key [32]byte
in := make([]byte, 1024)
b.SetBytes(int64(len(in)))
b.StartTimer()
for i := 0; i < b.N; i++ {
Sum(&out, in, &key)
}
}
func Benchmark64(b *testing.B) {
b.StopTimer()
var out [16]byte
var key [32]byte
in := make([]byte, 64)
b.SetBytes(int64(len(in)))
b.StartTimer()
for i := 0; i < b.N; i++ {
Sum(&out, in, &key)
}
}

View File

@ -3,7 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package salsa provides low-level access to functions in the Salsa family. // Package salsa provides low-level access to functions in the Salsa family.
package salsa // import "golang.org/x/crypto/salsa20/salsa" package salsa
// Sigma is the Salsa20 constant for 256-bit keys. // Sigma is the Salsa20 constant for 256-bit keys.
var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'} var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}

View File

@ -1,35 +0,0 @@
// Copyright 2012 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 salsa
import "testing"
func TestCore208(t *testing.T) {
in := [64]byte{
0x7e, 0x87, 0x9a, 0x21, 0x4f, 0x3e, 0xc9, 0x86,
0x7c, 0xa9, 0x40, 0xe6, 0x41, 0x71, 0x8f, 0x26,
0xba, 0xee, 0x55, 0x5b, 0x8c, 0x61, 0xc1, 0xb5,
0x0d, 0xf8, 0x46, 0x11, 0x6d, 0xcd, 0x3b, 0x1d,
0xee, 0x24, 0xf3, 0x19, 0xdf, 0x9b, 0x3d, 0x85,
0x14, 0x12, 0x1e, 0x4b, 0x5a, 0xc5, 0xaa, 0x32,
0x76, 0x02, 0x1d, 0x29, 0x09, 0xc7, 0x48, 0x29,
0xed, 0xeb, 0xc6, 0x8d, 0xb8, 0xb8, 0xc2, 0x5e}
out := [64]byte{
0xa4, 0x1f, 0x85, 0x9c, 0x66, 0x08, 0xcc, 0x99,
0x3b, 0x81, 0xca, 0xcb, 0x02, 0x0c, 0xef, 0x05,
0x04, 0x4b, 0x21, 0x81, 0xa2, 0xfd, 0x33, 0x7d,
0xfd, 0x7b, 0x1c, 0x63, 0x96, 0x68, 0x2f, 0x29,
0xb4, 0x39, 0x31, 0x68, 0xe3, 0xc9, 0xe6, 0xbc,
0xfe, 0x6b, 0xc5, 0xb7, 0xa0, 0x6d, 0x96, 0xba,
0xe4, 0x24, 0xcc, 0x10, 0x2c, 0x91, 0x74, 0x5c,
0x24, 0xad, 0x67, 0x3d, 0xc7, 0x61, 0x8f, 0x81,
}
Core208(&in, &in)
if in != out {
t.Errorf("expected %x, got %x", out, in)
}
}