forked from TrueCloudLab/tzhash
add SubtractR/L operation on hashes
- add Inverse operation to sl2 - fix a bug in xN()
This commit is contained in:
parent
ebb124e812
commit
d5efd8bdce
6 changed files with 146 additions and 19 deletions
|
@ -19,7 +19,7 @@ import (
|
|||
type GF127 [2]uint64
|
||||
|
||||
const (
|
||||
msb64 = 0x8000000000000000
|
||||
msb64 = uint64(0x8000000000000000)
|
||||
byteSize = 16
|
||||
)
|
||||
|
||||
|
@ -110,8 +110,7 @@ func Inv(a, b *GF127) {
|
|||
// becasuse mul performs reduction on t, we need
|
||||
// manually reduce u at first step
|
||||
if msb(&u) == 127 {
|
||||
Add(&u, &x127x63, &u)
|
||||
Add(&u, &GF127{1, 0}, &u)
|
||||
Add(&u, &x127x631, &u)
|
||||
}
|
||||
|
||||
Mul(x, d, t)
|
||||
|
@ -124,7 +123,7 @@ func xN(n int) *GF127 {
|
|||
if n < 64 {
|
||||
return &GF127{1 << uint(n), 0}
|
||||
}
|
||||
return &GF127{0, 1 << (uint(n) >> 8)}
|
||||
return &GF127{0, 1 << uint(n-64)}
|
||||
}
|
||||
|
||||
func msb(a *GF127) (x int) {
|
||||
|
|
|
@ -71,6 +71,7 @@ func TestMul11(t *testing.T) {
|
|||
|
||||
var testCasesInv = [][2]*GF127{
|
||||
{&GF127{1, 0}, &GF127{1, 0}},
|
||||
{&GF127{3, 0}, &GF127{msb64, ^msb64}},
|
||||
{&GF127{54321, 12345}, &GF127{8230555108620784737, 3929873967650665114}},
|
||||
}
|
||||
|
||||
|
|
38
tz/hash.go
38
tz/hash.go
|
@ -133,4 +133,42 @@ func Validate(h []byte, hs [][]byte) (bool, error) {
|
|||
return expected == got, nil
|
||||
}
|
||||
|
||||
// SubtractR returns hash a, such that Concat(a, b) == c
|
||||
// This is possible, because Tillich-Zemor hash is actually a matrix
|
||||
// which can be inversed.
|
||||
func SubtractR(c, b []byte) (a []byte, err error) {
|
||||
var p1, p2, r sl2
|
||||
|
||||
if err = r.UnmarshalBinary(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = p2.UnmarshalBinary(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p1 = *Inv(&p2)
|
||||
p1.Mul(&r, &p1)
|
||||
|
||||
return p1.MarshalBinary()
|
||||
}
|
||||
|
||||
// SubtractL returns hash b, such that Concat(a, b) == c
|
||||
// This is possible, because Tillich-Zemor hash is actually a matrix
|
||||
// which can be inversed.
|
||||
func SubtractL(c, a []byte) (b []byte, err error) {
|
||||
var p1, p2, r sl2
|
||||
|
||||
if err = r.UnmarshalBinary(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = p1.UnmarshalBinary(a); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p2 = *Inv(&p1)
|
||||
p2.Mul(&p2, &r)
|
||||
|
||||
return p2.MarshalBinary()
|
||||
}
|
||||
|
||||
func mulBitRight(c00, c01, c10, c11, e *gf127.GF127)
|
||||
|
|
|
@ -15,9 +15,9 @@ func TestHash(t *testing.T) {
|
|||
err error
|
||||
h, h1, h2 [hashSize]byte
|
||||
b []byte
|
||||
)
|
||||
|
||||
g := NewGomegaWithT(t)
|
||||
g = NewGomegaWithT(t)
|
||||
)
|
||||
|
||||
b = make([]byte, 64)
|
||||
n, err = rand.Read(b)
|
||||
|
@ -31,6 +31,7 @@ func TestHash(t *testing.T) {
|
|||
|
||||
err = c1.UnmarshalBinary(h1[:])
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = c2.UnmarshalBinary(h2[:])
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -62,9 +63,9 @@ func TestConcat(t *testing.T) {
|
|||
got, expected []byte
|
||||
ps [][]byte
|
||||
err error
|
||||
)
|
||||
|
||||
g := NewGomegaWithT(t)
|
||||
g = NewGomegaWithT(t)
|
||||
)
|
||||
|
||||
for _, tc := range testCases {
|
||||
expected, err = hex.DecodeString(tc.Hash)
|
||||
|
@ -107,3 +108,46 @@ func TestValidate(t *testing.T) {
|
|||
g.Expect(got).To(Equal(true))
|
||||
}
|
||||
}
|
||||
|
||||
var testCasesSubtract = []struct {
|
||||
first, second, result string
|
||||
}{
|
||||
{
|
||||
first: "4275945919296224acd268456be23b8b2df931787a46716477e32cd991e98074029d4f03a0fedc09125ee4640d228d7d40d430659a0b2b70e9cd4d4c5361865a",
|
||||
second: "277c10e0d7c52fcc0b23ba7dbf2c3dde7dcfc1f7c0cc0d998b2de504b8c1e17c6f65ab1294aea676d4060ed2ca18c1c26fd7cec5012ab69a4ddb5e6555ac8a59",
|
||||
result: "7f5c9280352a8debea738a74abd4ec787f2c5e556800525692f651087442f9883bb97a2c1bc72d12ba26e3df8dc0f670564292ebc984976a8e353ff69a5fb3cb",
|
||||
},
|
||||
{
|
||||
first: "18e2ce290cc74998ebd0bef76454b52a40428f13bb612e40b5b96187e9cc813248a0ed5f7ec9fb205d55d3f243e2211363f171b19eb8acc7931cf33853a79069",
|
||||
second: "73a0582fa7d00d62fd09c1cd18589cdb2b126cb58b3a022ae47a8a787dabe35c4388aaf0d8bb343b1e58ee8d267812d115f40a0da611f42458f452e102f60700",
|
||||
result: "54ccaad1bb15b2989fa31109713bca955ea5d87bbd3113b3008cea167c00052266e9c9fcb73ece98c6c08cccb074ba3d39b5d8685f022fc388e2bf1997c5bd1d",
|
||||
},
|
||||
}
|
||||
|
||||
func TestSubtract(t *testing.T) {
|
||||
var (
|
||||
a, b, c, r []byte
|
||||
err error
|
||||
|
||||
g = NewGomegaWithT(t)
|
||||
)
|
||||
|
||||
for _, tc := range testCasesSubtract {
|
||||
a, err = hex.DecodeString(tc.first)
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
b, err = hex.DecodeString(tc.second)
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
c, err = hex.DecodeString(tc.result)
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
r, err = SubtractR(c, b)
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
g.Expect(r).To(Equal(a))
|
||||
|
||||
r, err = SubtractL(c, a)
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
g.Expect(r).To(Equal(b))
|
||||
}
|
||||
}
|
||||
|
|
19
tz/sl2.go
19
tz/sl2.go
|
@ -132,6 +132,25 @@ func (c *sl2) Mul(a, b *sl2) *sl2 {
|
|||
return c.mul(a, b, new([4]gf127.GF127))
|
||||
}
|
||||
|
||||
// Inv returns inverse of a in GL_2(GF(2^127))
|
||||
func Inv(a *sl2) (b *sl2) {
|
||||
b = new(sl2)
|
||||
inv(a, b, new([2]gf127.GF127))
|
||||
return
|
||||
}
|
||||
|
||||
func inv(a, b *sl2, t *[2]gf127.GF127) {
|
||||
gf127.Mul(&a[0][0], &a[1][1], &t[0])
|
||||
gf127.Mul(&a[0][1], &a[1][0], &t[1])
|
||||
gf127.Add(&t[0], &t[1], &t[0])
|
||||
gf127.Inv(&t[0], &t[1])
|
||||
|
||||
gf127.Mul(&t[1], &a[0][0], &b[1][1])
|
||||
gf127.Mul(&t[1], &a[0][1], &b[0][1])
|
||||
gf127.Mul(&t[1], &a[1][0], &b[1][0])
|
||||
gf127.Mul(&t[1], &a[1][1], &b[0][0])
|
||||
}
|
||||
|
||||
func (c *sl2) String() string {
|
||||
return c[0][0].String() + c[0][1].String() +
|
||||
c[1][0].String() + c[1][1].String()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package tz
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -14,25 +13,52 @@ func init() {
|
|||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func u64() uint64 {
|
||||
return rand.Uint64() & (math.MaxUint64 >> 1)
|
||||
func random() (a *sl2) {
|
||||
a = new(sl2)
|
||||
a[0][0] = *gf127.Random()
|
||||
a[0][1] = *gf127.Random()
|
||||
a[1][0] = *gf127.Random()
|
||||
|
||||
// so that result is in SL2
|
||||
// d = a^-1*(1+b*c)
|
||||
gf127.Mul(&a[0][1], &a[1][0], &a[1][1])
|
||||
gf127.Add(&a[1][1], gf127.New(1, 0), &a[1][1])
|
||||
|
||||
t := gf127.New(0, 0)
|
||||
gf127.Inv(&a[0][0], t)
|
||||
gf127.Mul(t, &a[1][1], &a[1][1])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func TestSL2_MarshalBinary(t *testing.T) {
|
||||
g := NewGomegaWithT(t)
|
||||
|
||||
a := new(sl2)
|
||||
a[0][0] = *gf127.New(u64(), u64())
|
||||
a[0][1] = *gf127.New(u64(), u64())
|
||||
a[1][0] = *gf127.New(u64(), u64())
|
||||
a[1][1] = *gf127.New(u64(), u64())
|
||||
var (
|
||||
a = random()
|
||||
b = new(sl2)
|
||||
g = NewGomegaWithT(t)
|
||||
)
|
||||
|
||||
data, err := a.MarshalBinary()
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
b := new(sl2)
|
||||
err = b.UnmarshalBinary(data)
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
g.Expect(a).To(Equal(b))
|
||||
}
|
||||
|
||||
func TestInv(t *testing.T) {
|
||||
var (
|
||||
a, b, c *sl2
|
||||
g = NewGomegaWithT(t)
|
||||
)
|
||||
|
||||
c = new(sl2)
|
||||
for i := 0; i < 5; i++ {
|
||||
a = random()
|
||||
b = Inv(a)
|
||||
c = c.Mul(a, b)
|
||||
|
||||
g.Expect(*c).To(Equal(id))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue