mirror of
https://github.com/1f349/twofactor.git
synced 2024-12-22 07:24:12 +00:00
Regenerated dependencies with Godep
This commit is contained in:
parent
8199ae9abf
commit
9e163709ba
26
Godeps/Godeps.json
generated
26
Godeps/Godeps.json
generated
@ -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
27
Godeps/_workspace/src/code.google.com/p/rsc/LICENSE
generated
vendored
Normal 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.
|
85
Godeps/_workspace/src/code.google.com/p/rsc/gf256/blog_test.go
generated
vendored
85
Godeps/_workspace/src/code.google.com/p/rsc/gf256/blog_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
194
Godeps/_workspace/src/code.google.com/p/rsc/gf256/gf256_test.go
generated
vendored
194
Godeps/_workspace/src/code.google.com/p/rsc/gf256/gf256_test.go
generated
vendored
@ -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
|
|
||||||
}
|
|
133
Godeps/_workspace/src/code.google.com/p/rsc/qr/coding/qr_test.go
generated
vendored
133
Godeps/_workspace/src/code.google.com/p/rsc/qr/coding/qr_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
73
Godeps/_workspace/src/code.google.com/p/rsc/qr/png_test.go
generated
vendored
73
Godeps/_workspace/src/code.google.com/p/rsc/qr/png_test.go
generated
vendored
@ -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()))
|
|
||||||
}
|
|
61
Godeps/_workspace/src/github.com/sec51/convert/smallendian/convert_test.go
generated
vendored
61
Godeps/_workspace/src/github.com/sec51/convert/smallendian/convert_test.go
generated
vendored
@ -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")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
6
Godeps/_workspace/src/github.com/sec51/cryptoengine/.travis.yml
generated
vendored
6
Godeps/_workspace/src/github.com/sec51/cryptoengine/.travis.yml
generated
vendored
@ -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 ./...
|
||||||
|
34
Godeps/_workspace/src/github.com/sec51/cryptoengine/Godeps/Godeps.json
generated
vendored
Normal file
34
Godeps/_workspace/src/github.com/sec51/cryptoengine/Godeps/Godeps.json
generated
vendored
Normal 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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
5
Godeps/_workspace/src/github.com/sec51/cryptoengine/Godeps/Readme
generated
vendored
Normal file
5
Godeps/_workspace/src/github.com/sec51/cryptoengine/Godeps/Readme
generated
vendored
Normal 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.
|
2
Godeps/_workspace/src/github.com/sec51/cryptoengine/README.md
generated
vendored
2
Godeps/_workspace/src/github.com/sec51/cryptoengine/README.md
generated
vendored
@ -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
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
153
Godeps/_workspace/src/github.com/sec51/cryptoengine/crypto_engine.go
generated
vendored
153
Godeps/_workspace/src/github.com/sec51/cryptoengine/crypto_engine.go
generated
vendored
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -56,11 +58,12 @@ type CryptoEngine struct {
|
|||||||
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
|
|
||||||
sharedKey [keySize]byte // this is the precomputed key, between the peer aymmetric public key and the application asymmetric private key. This speeds up things.
|
|
||||||
salt [keySize]byte // salt for deriving the random nonces
|
salt [keySize]byte // salt for deriving the random nonces
|
||||||
nonceKey [keySize]byte // this key is used for deriving the random nonces. It's different from the privateKey
|
nonceKey [keySize]byte // this key is used for deriving the random nonces. It's different from the privateKey
|
||||||
preSharedInitialized bool // flag which tells if the preSharedKey has been initialized
|
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
|
||||||
|
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
|
||||||
|
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()
|
||||||
encryptedData := box.Seal(nil, msg.toBytes(), &m.nonce, &engine.peerPublicKey, &engine.privateKey)
|
|
||||||
|
// 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
|
// assign the encrypted data to the message
|
||||||
m.data = encryptedData
|
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
|
||||||
|
}
|
||||||
|
|
||||||
// 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(preSharedKey [keySize]byte, m EncryptedMessage) ([]byte, error) {
|
||||||
|
if decryptedMessage, valid := box.OpenAfterPrecomputation(nil, m.data, &m.nonce, &preSharedKey); !valid {
|
||||||
}
|
|
||||||
|
|
||||||
func decryptWithPreShared(engine *CryptoEngine, m EncryptedMessage) ([]byte, error) {
|
|
||||||
if decryptedMessage, valid := box.OpenAfterPrecomputation(nil, m.data, &m.nonce, &engine.sharedKey); !valid {
|
|
||||||
return nil, MessageDecryptionError
|
return nil, MessageDecryptionError
|
||||||
} else {
|
} else {
|
||||||
return decryptedMessage, nil
|
return decryptedMessage, nil
|
||||||
|
213
Godeps/_workspace/src/github.com/sec51/cryptoengine/crypto_engine_test.go
generated
vendored
213
Godeps/_workspace/src/github.com/sec51/cryptoengine/crypto_engine_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
111
Godeps/_workspace/src/github.com/sec51/cryptoengine/file_utils_test.go
generated
vendored
111
Godeps/_workspace/src/github.com/sec51/cryptoengine/file_utils_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
4
Godeps/_workspace/src/github.com/sec51/cryptoengine/hkdf.go
generated
vendored
4
Godeps/_workspace/src/github.com/sec51/cryptoengine/hkdf.go
generated
vendored
@ -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)
|
||||||
|
7
Godeps/_workspace/src/github.com/sec51/cryptoengine/message.go
generated
vendored
7
Godeps/_workspace/src/github.com/sec51/cryptoengine/message.go
generated
vendored
@ -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)
|
||||||
|
4
Godeps/_workspace/src/github.com/sec51/cryptoengine/verification_engine.go
generated
vendored
4
Godeps/_workspace/src/github.com/sec51/cryptoengine/verification_engine.go
generated
vendored
@ -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
27
Godeps/_workspace/src/github.com/sec51/rsc/LICENSE
generated
vendored
Normal 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.
|
149
Godeps/_workspace/src/github.com/sec51/rsc/qr/coding/gen.go
generated
vendored
Normal file
149
Godeps/_workspace/src/github.com/sec51/rsc/qr/coding/gen.go
generated
vendored
Normal 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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
815
Godeps/_workspace/src/github.com/sec51/rsc/qr/coding/qr.go
generated
vendored
Normal file
815
Godeps/_workspace/src/github.com/sec51/rsc/qr/coding/qr.go
generated
vendored
Normal 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
27
Godeps/_workspace/src/golang.org/x/crypto/LICENSE
generated
vendored
Normal 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
22
Godeps/_workspace/src/golang.org/x/crypto/PATENTS
generated
vendored
Normal 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.
|
29
Godeps/_workspace/src/golang.org/x/crypto/curve25519/curve25519_test.go
generated
vendored
29
Godeps/_workspace/src/golang.org/x/crypto/curve25519/curve25519_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
2
Godeps/_workspace/src/golang.org/x/crypto/curve25519/doc.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/crypto/curve25519/doc.go
generated
vendored
@ -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}
|
||||||
|
61
Godeps/_workspace/src/golang.org/x/crypto/hkdf/example_test.go
generated
vendored
61
Godeps/_workspace/src/golang.org/x/crypto/hkdf/example_test.go
generated
vendored
@ -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
|
|
||||||
}
|
|
2
Godeps/_workspace/src/golang.org/x/crypto/hkdf/hkdf.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/crypto/hkdf/hkdf.go
generated
vendored
@ -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"
|
||||||
|
370
Godeps/_workspace/src/golang.org/x/crypto/hkdf/hkdf_test.go
generated
vendored
370
Godeps/_workspace/src/golang.org/x/crypto/hkdf/hkdf_test.go
generated
vendored
@ -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--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
2
Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box.go
generated
vendored
@ -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"
|
||||||
|
78
Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box_test.go
generated
vendored
78
Godeps/_workspace/src/golang.org/x/crypto/nacl/box/box_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
2
Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox/secretbox.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox/secretbox.go
generated
vendored
@ -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"
|
||||||
|
91
Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox/secretbox_test.go
generated
vendored
91
Godeps/_workspace/src/golang.org/x/crypto/nacl/secretbox/secretbox_test.go
generated
vendored
@ -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.")
|
|
||||||
}
|
|
||||||
}
|
|
2
Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305.go
generated
vendored
@ -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"
|
||||||
|
|
||||||
|
54
Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_arm.s
generated
vendored
54
Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_arm.s
generated
vendored
@ -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
|
||||||
|
74
Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_test.go
generated
vendored
74
Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
2
Godeps/_workspace/src/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
generated
vendored
2
Godeps/_workspace/src/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
generated
vendored
@ -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'}
|
||||||
|
35
Godeps/_workspace/src/golang.org/x/crypto/salsa20/salsa/salsa_test.go
generated
vendored
35
Godeps/_workspace/src/golang.org/x/crypto/salsa20/salsa/salsa_test.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user