Refactor some key stuff

This commit is contained in:
Jimmy Song 2017-05-13 17:36:32 -07:00
parent 435925b60c
commit 4ee46b4a26
11 changed files with 190 additions and 204 deletions

View file

@ -25,14 +25,18 @@ var FeFffb4 = FieldElement{-21786234, -12173074, 21573800, 4524538, -4645904, 16
var FeSqrtM1 = FieldElement{-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482} /* sqrt(-1) */ var FeSqrtM1 = FieldElement{-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482} /* sqrt(-1) */
var zero FieldElement var zero FieldElement
var one FieldElement
func FeZero(fe *FieldElement) { func init() {
copy(fe[:], zero[:]) one[0] = 1
} }
func FeOne(fe *FieldElement) { func (f *FieldElement) Zero() {
FeZero(fe) copy(f[:], zero[:])
fe[0] = 1 }
func (f *FieldElement) One() {
copy(f[:], one[:])
} }
func FeAdd(dst, a, b *FieldElement) { func FeAdd(dst, a, b *FieldElement) {
@ -83,24 +87,17 @@ func FeCMove(f, g *FieldElement, b int32) {
f[9] ^= b & (f[9] ^ g[9]) f[9] ^= b & (f[9] ^ g[9])
} }
func load3(in []byte) int64 { func load3(in []byte) (result int64) {
var r int64 result = int64(in[0]) | (int64(in[1]) << 8) | (int64(in[2]) << 16)
r = int64(in[0]) return
r |= int64(in[1]) << 8
r |= int64(in[2]) << 16
return r
} }
func load4(in []byte) int64 { func load4(in []byte) (result int64) {
var r int64 result = int64(in[0]) | (int64(in[1]) << 8) | (int64(in[2]) << 16) | (int64(in[3]) << 24)
r = int64(in[0]) return
r |= int64(in[1]) << 8
r |= int64(in[2]) << 16
r |= int64(in[3]) << 24
return r
} }
func FeFromBytes(dst *FieldElement, src *[32]byte) { func FeFromBytes(dst *FieldElement, src *Key) {
h0 := load4(src[:]) h0 := load4(src[:])
h1 := load3(src[4:]) << 6 h1 := load3(src[4:]) << 6
h2 := load3(src[7:]) << 5 h2 := load3(src[7:]) << 5
@ -138,7 +135,7 @@ func FeFromBytes(dst *FieldElement, src *[32]byte) {
// //
// Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1)) // Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
// so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. // so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
func FeToBytes(s *[32]byte, h *FieldElement) { func FeToBytes(s *Key, h *FieldElement) {
var carry [10]int32 var carry [10]int32
q := (19*h[9] + (1 << 24)) >> 25 q := (19*h[9] + (1 << 24)) >> 25
@ -227,14 +224,14 @@ func FeToBytes(s *[32]byte, h *FieldElement) {
s[31] = byte(h[9] >> 18) s[31] = byte(h[9] >> 18)
} }
func FeIsNegative(f *FieldElement) byte { func (f *FieldElement) IsNegative() byte {
var s [32]byte var s Key
FeToBytes(&s, f) FeToBytes(&s, f)
return s[0] & 1 return s[0] & 1
} }
func FeIsNonZero(f *FieldElement) int32 { func (f *FieldElement) IsNonZero() int32 {
var s [32]byte var s Key
FeToBytes(&s, f) FeToBytes(&s, f)
var x uint8 var x uint8
for _, b := range s { for _, b := range s {
@ -674,9 +671,9 @@ type CachedGroupElement struct {
} }
func (p *ProjectiveGroupElement) Zero() { func (p *ProjectiveGroupElement) Zero() {
FeZero(&p.X) p.X.Zero()
FeOne(&p.Y) p.Y.One()
FeOne(&p.Z) p.Z.One()
} }
func (p *ProjectiveGroupElement) Double(r *CompletedGroupElement) { func (p *ProjectiveGroupElement) Double(r *CompletedGroupElement) {
@ -693,17 +690,17 @@ func (p *ProjectiveGroupElement) Double(r *CompletedGroupElement) {
FeSub(&r.T, &r.T, &r.Z) FeSub(&r.T, &r.T, &r.Z)
} }
func (p *ProjectiveGroupElement) ToBytes(s *[32]byte) { func (p *ProjectiveGroupElement) ToBytes(s *Key) {
var recip, x, y FieldElement var recip, x, y FieldElement
FeInvert(&recip, &p.Z) FeInvert(&recip, &p.Z)
FeMul(&x, &p.X, &recip) FeMul(&x, &p.X, &recip)
FeMul(&y, &p.Y, &recip) FeMul(&y, &p.Y, &recip)
FeToBytes(s, &y) FeToBytes(s, &y)
s[31] ^= FeIsNegative(&x) << 7 s[31] ^= x.IsNegative() << 7
} }
func (p *ProjectiveGroupElement) FromBytes(s *[32]byte) { func (p *ProjectiveGroupElement) FromBytes(s *Key) {
h0 := load4(s[:]) h0 := load4(s[:])
h1 := load3(s[4:]) << 6 h1 := load3(s[4:]) << 6
h2 := load3(s[7:]) << 5 h2 := load3(s[7:]) << 5
@ -759,7 +756,7 @@ func (p *ProjectiveGroupElement) FromBytes(s *[32]byte) {
u[8] = int32(h8) u[8] = int32(h8)
u[9] = int32(h9) u[9] = int32(h9)
FeSquare2(&v, &u) /* 2 * u^2 */ FeSquare2(&v, &u) /* 2 * u^2 */
FeOne(&w) w.One()
FeAdd(&w, &v, &w) /* w = 2 * u^2 + 1 */ FeAdd(&w, &v, &w) /* w = 2 * u^2 + 1 */
FeSquare(&x, &w) /* w^2 */ FeSquare(&x, &w) /* w^2 */
FeMul(&y, &FeMa2, &v) /* -2 * A^2 * u^2 */ FeMul(&y, &FeMa2, &v) /* -2 * A^2 * u^2 */
@ -771,9 +768,9 @@ func (p *ProjectiveGroupElement) FromBytes(s *[32]byte) {
FeCopy(&z, &FeMa) FeCopy(&z, &FeMa)
isNegative := false isNegative := false
var sign byte var sign byte
if FeIsNonZero(&y) != 0 { if y.IsNonZero() != 0 {
FeAdd(&y, &w, &x) FeAdd(&y, &w, &x)
if FeIsNonZero(&y) != 0 { if y.IsNonZero() != 0 {
isNegative = true isNegative = true
} else { } else {
FeMul(&p.X, &p.X, &FeFffb1) FeMul(&p.X, &p.X, &FeFffb1)
@ -784,7 +781,7 @@ func (p *ProjectiveGroupElement) FromBytes(s *[32]byte) {
if isNegative { if isNegative {
FeMul(&x, &x, &FeSqrtM1) FeMul(&x, &x, &FeSqrtM1)
FeSub(&y, &w, &x) FeSub(&y, &w, &x)
if FeIsNonZero(&y) != 0 { if y.IsNonZero() != 0 {
FeAdd(&y, &w, &x) FeAdd(&y, &w, &x)
FeMul(&p.X, &p.X, &FeFffb3) FeMul(&p.X, &p.X, &FeFffb3)
} else { } else {
@ -798,7 +795,7 @@ func (p *ProjectiveGroupElement) FromBytes(s *[32]byte) {
FeMul(&z, &z, &v) /* -2 * A * u^2 */ FeMul(&z, &z, &v) /* -2 * A * u^2 */
sign = 0 sign = 0
} }
if FeIsNegative(&p.X) != sign { if p.X.IsNegative() != sign {
FeNeg(&p.X, &p.X) FeNeg(&p.X, &p.X)
} }
FeAdd(&p.Z, &z, &w) FeAdd(&p.Z, &z, &w)
@ -807,10 +804,10 @@ func (p *ProjectiveGroupElement) FromBytes(s *[32]byte) {
} }
func (p *ExtendedGroupElement) Zero() { func (p *ExtendedGroupElement) Zero() {
FeZero(&p.X) p.X.Zero()
FeOne(&p.Y) p.Y.One()
FeOne(&p.Z) p.Z.One()
FeZero(&p.T) p.T.Zero()
} }
func (p *ExtendedGroupElement) Double(r *CompletedGroupElement) { func (p *ExtendedGroupElement) Double(r *CompletedGroupElement) {
@ -832,21 +829,21 @@ func (p *ExtendedGroupElement) ToProjective(r *ProjectiveGroupElement) {
FeCopy(&r.Z, &p.Z) FeCopy(&r.Z, &p.Z)
} }
func (p *ExtendedGroupElement) ToBytes(s *[32]byte) { func (p *ExtendedGroupElement) ToBytes(s *Key) {
var recip, x, y FieldElement var recip, x, y FieldElement
FeInvert(&recip, &p.Z) FeInvert(&recip, &p.Z)
FeMul(&x, &p.X, &recip) FeMul(&x, &p.X, &recip)
FeMul(&y, &p.Y, &recip) FeMul(&y, &p.Y, &recip)
FeToBytes(s, &y) FeToBytes(s, &y)
s[31] ^= FeIsNegative(&x) << 7 s[31] ^= x.IsNegative() << 7
} }
func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool { func (p *ExtendedGroupElement) FromBytes(s *Key) bool {
var u, v, v3, vxx, check FieldElement var u, v, v3, vxx, check FieldElement
FeFromBytes(&p.Y, s) FeFromBytes(&p.Y, s)
FeOne(&p.Z) p.Z.One()
FeSquare(&u, &p.Y) FeSquare(&u, &p.Y)
FeMul(&v, &u, &d) FeMul(&v, &u, &d)
FeSub(&u, &u, &p.Z) // y = y^2-1 FeSub(&u, &u, &p.Z) // y = y^2-1
@ -862,14 +859,14 @@ func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool {
FeMul(&p.X, &p.X, &v3) FeMul(&p.X, &p.X, &v3)
FeMul(&p.X, &p.X, &u) // x = uv^3(uv^7)^((q-5)/8) FeMul(&p.X, &p.X, &u) // x = uv^3(uv^7)^((q-5)/8)
var tmpX, tmp2 [32]byte var tmpX, tmp2 Key
FeSquare(&vxx, &p.X) FeSquare(&vxx, &p.X)
FeMul(&vxx, &vxx, &v) FeMul(&vxx, &vxx, &v)
FeSub(&check, &vxx, &u) // vx^2-u FeSub(&check, &vxx, &u) // vx^2-u
if FeIsNonZero(&check) == 1 { if check.IsNonZero() == 1 {
FeAdd(&check, &vxx, &u) // vx^2+u FeAdd(&check, &vxx, &u) // vx^2+u
if FeIsNonZero(&check) == 1 { if check.IsNonZero() == 1 {
return false return false
} }
FeMul(&p.X, &p.X, &SqrtM1) FeMul(&p.X, &p.X, &SqrtM1)
@ -880,7 +877,7 @@ func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool {
} }
} }
if FeIsNegative(&p.X) != (s[31] >> 7) { if p.X.IsNegative() != (s[31] >> 7) {
FeNeg(&p.X, &p.X) FeNeg(&p.X, &p.X)
} }
@ -902,16 +899,16 @@ func (p *CompletedGroupElement) ToExtended(r *ExtendedGroupElement) {
} }
func (p *PreComputedGroupElement) Zero() { func (p *PreComputedGroupElement) Zero() {
FeOne(&p.yPlusX) p.yPlusX.One()
FeOne(&p.yMinusX) p.yMinusX.One()
FeZero(&p.xy2d) p.xy2d.Zero()
} }
func (c *CachedGroupElement) Zero() { func (c *CachedGroupElement) Zero() {
FeOne(&c.yPlusX) c.yPlusX.One()
FeOne(&c.yMinusX) c.yMinusX.One()
FeOne(&c.Z) c.Z.One()
FeZero(&c.T2d) c.T2d.Zero()
} }
func geAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) { func geAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) {
@ -1000,7 +997,7 @@ func GePrecompute(r *[8]CachedGroupElement, s *ExtendedGroupElement) {
} }
} }
func slide(r *[256]int8, a *[32]byte) { func slide(r *[256]int8, a *Key) {
for i := range r { for i := range r {
r[i] = int8(1 & (a[i>>3] >> uint(i&7))) r[i] = int8(1 & (a[i>>3] >> uint(i&7)))
} }
@ -1034,7 +1031,7 @@ func slide(r *[256]int8, a *[32]byte) {
// where a = a[0]+256*a[1]+...+256^31 a[31]. // where a = a[0]+256*a[1]+...+256^31 a[31].
// and b = b[0]+256*b[1]+...+256^31 b[31]. // and b = b[0]+256*b[1]+...+256^31 b[31].
// B is the Ed25519 base point (x,4/5) with x positive. // B is the Ed25519 base point (x,4/5) with x positive.
func GeDoubleScalarMultVartime(r *ProjectiveGroupElement, a *[32]byte, A *ExtendedGroupElement, b *[32]byte) { func GeDoubleScalarMultVartime(r *ProjectiveGroupElement, a *Key, A *ExtendedGroupElement, b *Key) {
var aSlide, bSlide [256]int8 var aSlide, bSlide [256]int8
var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A
var t CompletedGroupElement var t CompletedGroupElement
@ -1079,7 +1076,7 @@ func GeDoubleScalarMultVartime(r *ProjectiveGroupElement, a *[32]byte, A *Extend
// sets r = a*A + b*B // sets r = a*A + b*B
// where Bi is the [8]CachedGroupElement consisting of // where Bi is the [8]CachedGroupElement consisting of
// B,3B,5B,7B,9B,11B,13B,15B // B,3B,5B,7B,9B,11B,13B,15B
func GeDoubleScalarMultPrecompVartime(r *ProjectiveGroupElement, a *[32]byte, A *ExtendedGroupElement, b *[32]byte, Bi *[8]CachedGroupElement) { func GeDoubleScalarMultPrecompVartime(r *ProjectiveGroupElement, a *Key, A *ExtendedGroupElement, b *Key, Bi *[8]CachedGroupElement) {
var aSlide, bSlide [256]int8 var aSlide, bSlide [256]int8
var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A
var t CompletedGroupElement var t CompletedGroupElement
@ -1161,7 +1158,7 @@ func selectPoint(t *PreComputedGroupElement, pos int32, b int32) {
// //
// Preconditions: // Preconditions:
// a[31] <= 127 // a[31] <= 127
func GeScalarMult(r *ProjectiveGroupElement, a *[32]byte, A *ExtendedGroupElement) { func GeScalarMult(r *ProjectiveGroupElement, a *Key, A *ExtendedGroupElement) {
var e [64]int32 var e [64]int32
var carry, carry2 int32 var carry, carry2 int32
for i := 0; i < 31; i++ { for i := 0; i < 31; i++ {
@ -1220,7 +1217,7 @@ func GeScalarMult(r *ProjectiveGroupElement, a *[32]byte, A *ExtendedGroupElemen
// //
// Preconditions: // Preconditions:
// a[31] <= 127 // a[31] <= 127
func GeScalarMultBase(h *ExtendedGroupElement, a *[32]byte) { func GeScalarMultBase(h *ExtendedGroupElement, a *Key) {
var e [64]int8 var e [64]int8
for i, v := range a { for i, v := range a {
@ -1266,7 +1263,7 @@ func GeScalarMultBase(h *ExtendedGroupElement, a *[32]byte) {
} }
} }
func ScAdd(s, a, b *[32]byte) { func ScAdd(s, a, b *Key) {
a0 := 2097151 & load3(a[:]) a0 := 2097151 & load3(a[:])
a1 := 2097151 & (load4(a[2:]) >> 5) a1 := 2097151 & (load4(a[2:]) >> 5)
a2 := 2097151 & (load3(a[5:]) >> 2) a2 := 2097151 & (load3(a[5:]) >> 2)
@ -1464,7 +1461,7 @@ func ScAdd(s, a, b *[32]byte) {
s[31] = byte(s11 >> 17) s[31] = byte(s11 >> 17)
} }
func ScSub(s, a, b *[32]byte) { func ScSub(s, a, b *Key) {
a0 := 2097151 & load3(a[:]) a0 := 2097151 & load3(a[:])
a1 := 2097151 & (load4(a[2:]) >> 5) a1 := 2097151 & (load4(a[2:]) >> 5)
a2 := 2097151 & (load3(a[5:]) >> 2) a2 := 2097151 & (load3(a[5:]) >> 2)
@ -1666,7 +1663,7 @@ func signum(a int64) int64 {
return a>>63 - ((-a) >> 63) return a>>63 - ((-a) >> 63)
} }
func ScValid(s *[32]byte) bool { func ScValid(s *Key) bool {
s0 := load4(s[:]) s0 := load4(s[:])
s1 := load4(s[4:]) s1 := load4(s[4:])
s2 := load4(s[8:]) s2 := load4(s[8:])
@ -1679,7 +1676,7 @@ func ScValid(s *[32]byte) bool {
} }
func ScIsZero(s *[32]byte) bool { func ScIsZero(s *Key) bool {
return ((int(s[0]|s[1]|s[2]|s[3]|s[4]|s[5]|s[6]|s[7]|s[8]| return ((int(s[0]|s[1]|s[2]|s[3]|s[4]|s[5]|s[6]|s[7]|s[8]|
s[9]|s[10]|s[11]|s[12]|s[13]|s[14]|s[15]|s[16]|s[17]| s[9]|s[10]|s[11]|s[12]|s[13]|s[14]|s[15]|s[16]|s[17]|
s[18]|s[19]|s[20]|s[21]|s[22]|s[23]|s[24]|s[25]|s[26]| s[18]|s[19]|s[20]|s[21]|s[22]|s[23]|s[24]|s[25]|s[26]|
@ -1696,7 +1693,7 @@ func ScIsZero(s *[32]byte) bool {
// Output: // Output:
// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l // s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
// where l = 2^252 + 27742317777372353535851937790883648493. // where l = 2^252 + 27742317777372353535851937790883648493.
func ScMulAdd(s, a, b, c *[32]byte) { func ScMulAdd(s, a, b, c *Key) {
a0 := 2097151 & load3(a[:]) a0 := 2097151 & load3(a[:])
a1 := 2097151 & (load4(a[2:]) >> 5) a1 := 2097151 & (load4(a[2:]) >> 5)
a2 := 2097151 & (load3(a[5:]) >> 2) a2 := 2097151 & (load3(a[5:]) >> 2)
@ -2129,7 +2126,7 @@ func ScMulAdd(s, a, b, c *[32]byte) {
// Output: // Output:
// s[0]+256*s[1]+...+256^31*s[31] = (c-ab) mod l // s[0]+256*s[1]+...+256^31*s[31] = (c-ab) mod l
// where l = 2^252 + 27742317777372353535851937790883648493. // where l = 2^252 + 27742317777372353535851937790883648493.
func ScMulSub(s, a, b, c *[32]byte) { func ScMulSub(s, a, b, c *Key) {
a0 := 2097151 & load3(a[:]) a0 := 2097151 & load3(a[:])
a1 := 2097151 & (load4(a[2:]) >> 5) a1 := 2097151 & (load4(a[2:]) >> 5)
a2 := 2097151 & (load3(a[5:]) >> 2) a2 := 2097151 & (load3(a[5:]) >> 2)
@ -2560,7 +2557,7 @@ func ScMulSub(s, a, b, c *[32]byte) {
// Output: // Output:
// s[0]+256*s[1]+...+256^31*s[31] = s mod l // s[0]+256*s[1]+...+256^31*s[31] = s mod l
// where l = 2^252 + 27742317777372353535851937790883648493. // where l = 2^252 + 27742317777372353535851937790883648493.
func ScReduce(out *[32]byte, s *[64]byte) { func ScReduce(out *Key, s *[64]byte) {
s0 := 2097151 & load3(s[:]) s0 := 2097151 & load3(s[:])
s1 := 2097151 & (load4(s[2:]) >> 5) s1 := 2097151 & (load4(s[2:]) >> 5)
s2 := 2097151 & (load3(s[5:]) >> 2) s2 := 2097151 & (load3(s[5:]) >> 2)
@ -2878,7 +2875,7 @@ func ScReduce(out *[32]byte, s *[64]byte) {
out[31] = byte(s11 >> 17) out[31] = byte(s11 >> 17)
} }
func ScReduce32(s *[32]byte) { func ScReduce32(s *Key) {
s0 := 2097151 & load3(s[:]) s0 := 2097151 & load3(s[:])
s1 := 2097151 & (load4(s[2:]) >> 5) s1 := 2097151 & (load4(s[2:]) >> 5)
s2 := 2097151 & (load3(s[5:]) >> 2) s2 := 2097151 & (load3(s[5:]) >> 2)

View file

@ -35,11 +35,11 @@ func TestScMulSub(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
a := HexToBytes(test.aHex) a := HexToKey(test.aHex)
b := HexToBytes(test.bHex) b := HexToKey(test.bHex)
c := HexToBytes(test.cHex) c := HexToKey(test.cHex)
want := HexToBytes(test.wantHex) want := HexToKey(test.wantHex)
var got [32]byte var got Key
ScMulSub(&got, &a, &b, &c) ScMulSub(&got, &a, &b, &c)
if want != got { if want != got {
t.Errorf("%s: want %x, got %x", test.name, want, got) t.Errorf("%s: want %x, got %x", test.name, want, got)
@ -80,14 +80,14 @@ func TestScalarMult(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
scalarBytes := HexToBytes(test.scalarHex) scalarBytes := HexToKey(test.scalarHex)
pointBytes := HexToBytes(test.pointHex) pointBytes := HexToKey(test.pointHex)
want := HexToBytes(test.wantHex) want := HexToKey(test.wantHex)
point := new(ExtendedGroupElement) point := new(ExtendedGroupElement)
point.FromBytes(&pointBytes) point.FromBytes(&pointBytes)
result := new(ProjectiveGroupElement) result := new(ProjectiveGroupElement)
GeScalarMult(result, &scalarBytes, point) GeScalarMult(result, &scalarBytes, point)
var got [32]byte var got Key
result.ToBytes(&got) result.ToBytes(&got)
if want != got { if want != got {
t.Errorf("%s: want %x, got %x", test.name, want, got) t.Errorf("%s: want %x, got %x", test.name, want, got)
@ -113,15 +113,15 @@ func TestGeMul8(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
pointBytes := HexToBytes(test.pointHex) pointBytes := HexToKey(test.pointHex)
want := HexToBytes(test.wantHex) want := HexToKey(test.wantHex)
tmp := new(ExtendedGroupElement) tmp := new(ExtendedGroupElement)
tmp.FromBytes(&pointBytes) tmp.FromBytes(&pointBytes)
point := new(ProjectiveGroupElement) point := new(ProjectiveGroupElement)
tmp.ToProjective(point) tmp.ToProjective(point)
tmp2 := new(CompletedGroupElement) tmp2 := new(CompletedGroupElement)
result := new(ExtendedGroupElement) result := new(ExtendedGroupElement)
var got [32]byte var got Key
GeMul8(tmp2, point) GeMul8(tmp2, point)
tmp2.ToExtended(result) tmp2.ToExtended(result)
result.ToBytes(&got) result.ToBytes(&got)
@ -169,15 +169,15 @@ func TestGeDoubleScalarMultVartime(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
pointBytes := HexToBytes(test.pointHex) pointBytes := HexToKey(test.pointHex)
a := HexToBytes(test.scalar1Hex) a := HexToKey(test.scalar1Hex)
b := HexToBytes(test.scalar2Hex) b := HexToKey(test.scalar2Hex)
want := HexToBytes(test.wantHex) want := HexToKey(test.wantHex)
point := new(ExtendedGroupElement) point := new(ExtendedGroupElement)
point.FromBytes(&pointBytes) point.FromBytes(&pointBytes)
result := new(ProjectiveGroupElement) result := new(ProjectiveGroupElement)
GeDoubleScalarMultVartime(result, &a, point, &b) GeDoubleScalarMultVartime(result, &a, point, &b)
var got [32]byte var got Key
result.ToBytes(&got) result.ToBytes(&got)
if want != got { if want != got {
t.Errorf("%s: want %x, got %x", test.name, want, got) t.Errorf("%s: want %x, got %x", test.name, want, got)
@ -228,11 +228,11 @@ func TestGeDoubleScalarMultPrecompVartime(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
point1Bytes := HexToBytes(test.point1Hex) point1Bytes := HexToKey(test.point1Hex)
point2Bytes := HexToBytes(test.point2Hex) point2Bytes := HexToKey(test.point2Hex)
a := HexToBytes(test.scalar1Hex) a := HexToKey(test.scalar1Hex)
b := HexToBytes(test.scalar2Hex) b := HexToKey(test.scalar2Hex)
want := HexToBytes(test.wantHex) want := HexToKey(test.wantHex)
point1 := new(ExtendedGroupElement) point1 := new(ExtendedGroupElement)
point1.FromBytes(&point1Bytes) point1.FromBytes(&point1Bytes)
point2 := new(ExtendedGroupElement) point2 := new(ExtendedGroupElement)
@ -241,7 +241,7 @@ func TestGeDoubleScalarMultPrecompVartime(t *testing.T) {
GePrecompute(&point2Precomp, point2) GePrecompute(&point2Precomp, point2)
result := new(ProjectiveGroupElement) result := new(ProjectiveGroupElement)
GeDoubleScalarMultPrecompVartime(result, &a, point1, &b, &point2Precomp) GeDoubleScalarMultPrecompVartime(result, &a, point1, &b, &point2Precomp)
var got [32]byte var got Key
result.ToBytes(&got) result.ToBytes(&got)
if want != got { if want != got {
t.Errorf("%s: want %x, got %x", test.name, want, got) t.Errorf("%s: want %x, got %x", test.name, want, got)
@ -1605,7 +1605,7 @@ func TestScValid(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
scalar := HexToBytes(test.scalarHex) scalar := HexToKey(test.scalarHex)
got := ScValid(&scalar) got := ScValid(&scalar)
if test.valid != got { if test.valid != got {
t.Errorf("%x: want %t, got %t", scalar, test.valid, got) t.Errorf("%x: want %t, got %t", scalar, test.valid, got)

View file

@ -4,7 +4,13 @@ import (
"encoding/hex" "encoding/hex"
) )
func HexToBytes(h string) (result [32]byte) { func HexToKey(h string) (result Key) {
byteSlice, _ := hex.DecodeString(h)
copy(result[:], byteSlice)
return
}
func HexToHash(h string) (result Hash) {
byteSlice, _ := hex.DecodeString(h) byteSlice, _ := hex.DecodeString(h)
copy(result[:], byteSlice) copy(result[:], byteSlice)
return return

View file

@ -1,7 +1,6 @@
package moneroutil package moneroutil
import ( import (
"bytes"
"encoding/hex" "encoding/hex"
"testing" "testing"
) )
@ -36,8 +35,8 @@ func TestKeccak256(t *testing.T) {
for _, test := range tests { for _, test := range tests {
message, _ := hex.DecodeString(test.messageHex) message, _ := hex.DecodeString(test.messageHex)
got := Keccak256(message) got := Keccak256(message)
want := HexToBytes(test.wantHex) want := HexToHash(test.wantHex)
if bytes.Compare(want[:], got[:]) != 0 { if want != got {
t.Errorf("want %x, got %x", want, got) t.Errorf("want %x, got %x", want, got)
} }
} }

51
key.go
View file

@ -5,66 +5,53 @@ import (
) )
const ( const (
PointLength = 32 KeyLength = 32
ScalarLength = 32
) )
type PubKey [PointLength]byte // Key can be a Scalar or a Point
type PrivKey [ScalarLength]byte type Key [KeyLength]byte
func (p *PrivKey) FromBytes(b [ScalarLength]byte) { func (p *Key) FromBytes(b [KeyLength]byte) {
*p = b *p = b
} }
func (p *PrivKey) ToBytes() (result [ScalarLength]byte) { func (p *Key) ToBytes() (result [KeyLength]byte) {
result = [32]byte(*p) result = [KeyLength]byte(*p)
return return
} }
func (p *PrivKey) PubKey() (pubKey *PubKey) { func (p *Key) PubKey() (pubKey *Key) {
secret := p.ToBytes()
point := new(ExtendedGroupElement) point := new(ExtendedGroupElement)
GeScalarMultBase(point, &secret) GeScalarMultBase(point, p)
pubKeyBytes := new([PointLength]byte) pubKey = new(Key)
point.ToBytes(pubKeyBytes) point.ToBytes(pubKey)
pubKey = (*PubKey)(pubKeyBytes)
return
}
func (p *PubKey) FromBytes(b [PointLength]byte) {
*p = b
}
func (p *PubKey) ToBytes() (result [PointLength]byte) {
result = [PointLength]byte(*p)
return return
} }
// Creates a point on the Edwards Curve by hashing the key // Creates a point on the Edwards Curve by hashing the key
func (p *PubKey) HashToEC() (result *ExtendedGroupElement) { func (p *Key) HashToEC() (result *ExtendedGroupElement) {
result = new(ExtendedGroupElement) result = new(ExtendedGroupElement)
var p1 ProjectiveGroupElement var p1 ProjectiveGroupElement
var p2 CompletedGroupElement var p2 CompletedGroupElement
h := [PointLength]byte(Keccak256(p[:])) h := Key(Keccak256(p[:]))
p1.FromBytes(&h) p1.FromBytes(&h)
GeMul8(&p2, &p1) GeMul8(&p2, &p1)
p2.ToExtended(result) p2.ToExtended(result)
return return
} }
func RandomScalar() (result [ScalarLength]byte) { func RandomScalar() (result *Key) {
var reduceFrom [ScalarLength * 2]byte result = new(Key)
tmp := make([]byte, ScalarLength*2) var reduceFrom [KeyLength * 2]byte
tmp := make([]byte, KeyLength*2)
rand.Read(tmp) rand.Read(tmp)
copy(reduceFrom[:], tmp) copy(reduceFrom[:], tmp)
ScReduce(&result, &reduceFrom) ScReduce(result, &reduceFrom)
return return
} }
func NewKeyPair() (privKey *PrivKey, pubKey *PubKey) { func NewKeyPair() (privKey *Key, pubKey *Key) {
privKey = new(PrivKey) privKey = RandomScalar()
pubKey = new(PubKey)
privKey.FromBytes(RandomScalar())
pubKey = privKey.PubKey() pubKey = privKey.PubKey()
return return
} }

View file

@ -9,13 +9,8 @@ const (
RCTTypeNull = iota RCTTypeNull = iota
RCTTypeFull RCTTypeFull
RCTTypeSimple RCTTypeSimple
KeyLength = 32
) )
// Key for Confidential Transactions, can be private or public
type Key [KeyLength]byte
// V = Vector, M = Matrix // V = Vector, M = Matrix
type KeyV []Key type KeyV []Key
type KeyM []KeyV type KeyM []KeyV

View file

@ -7,45 +7,53 @@ import (
) )
type RingSignatureElement struct { type RingSignatureElement struct {
c [ScalarLength]byte c *Key
r [ScalarLength]byte r *Key
} }
type RingSignature []*RingSignatureElement type RingSignature []*RingSignatureElement
func (r *RingSignatureElement) Serialize() (result []byte) { func (r *RingSignatureElement) Serialize() (result []byte) {
result = make([]byte, 2*ScalarLength) result = make([]byte, 2*KeyLength)
copy(result[:ScalarLength], r.c[:]) copy(result[:KeyLength], r.c[:])
copy(result[ScalarLength:2*ScalarLength], r.r[:]) copy(result[KeyLength:2*KeyLength], r.r[:])
return return
} }
func (r *RingSignature) Serialize() (result []byte) { func (r *RingSignature) Serialize() (result []byte) {
result = make([]byte, len(*r)*ScalarLength*2) result = make([]byte, len(*r)*KeyLength*2)
for i := 0; i < len(*r); i++ { for i := 0; i < len(*r); i++ {
copy(result[i*ScalarLength*2:(i+1)*ScalarLength*2], (*r)[i].Serialize()) copy(result[i*KeyLength*2:(i+1)*KeyLength*2], (*r)[i].Serialize())
}
return
}
func NewRingSignatureElement() (r *RingSignatureElement) {
r = &RingSignatureElement{
c: new(Key),
r: new(Key),
} }
return return
} }
func ParseSignature(buf io.Reader) (result *RingSignatureElement, err error) { func ParseSignature(buf io.Reader) (result *RingSignatureElement, err error) {
rse := new(RingSignatureElement) rse := NewRingSignatureElement()
c := make([]byte, ScalarLength) c := make([]byte, KeyLength)
n, err := buf.Read(c) n, err := buf.Read(c)
if err != nil { if err != nil {
return return
} }
if n != ScalarLength { if n != KeyLength {
err = fmt.Errorf("Not enough bytes for signature c") err = fmt.Errorf("Not enough bytes for signature c")
return return
} }
copy(rse.c[:], c) copy(rse.c[:], c)
r := make([]byte, ScalarLength) r := make([]byte, KeyLength)
n, err = buf.Read(r) n, err = buf.Read(r)
if err != nil { if err != nil {
return return
} }
if n != ScalarLength { if n != KeyLength {
err = fmt.Errorf("Not enough bytes for signature r") err = fmt.Errorf("Not enough bytes for signature r")
return return
} }
@ -70,43 +78,41 @@ func ParseSignatures(mixinLengths []int, buf io.Reader) (signatures []RingSignat
return return
} }
func HashToScalar(data ...[]byte) (result [ScalarLength]byte) { func HashToScalar(data ...[]byte) (result *Key) {
result = Keccak256(data...) result = new(Key)
ScReduce32(&result) *result = Key(Keccak256(data...))
ScReduce32(result)
return return
} }
func CreateSignature(prefixHash *Hash, mixins []PubKey, privKey *PrivKey) (keyImage PubKey, pubKeys []PubKey, sig RingSignature) { func CreateSignature(prefixHash *Hash, mixins []Key, privKey *Key) (keyImage Key, pubKeys []Key, sig RingSignature) {
point := privKey.PubKey().HashToEC() point := privKey.PubKey().HashToEC()
privKeyBytes := privKey.ToBytes()
keyImagePoint := new(ProjectiveGroupElement) keyImagePoint := new(ProjectiveGroupElement)
GeScalarMult(keyImagePoint, &privKeyBytes, point) GeScalarMult(keyImagePoint, privKey, point)
var keyImageBytes [PointLength]byte
// convert key Image point from Projective to Extended // convert key Image point from Projective to Extended
// in order to precompute // in order to precompute
keyImagePoint.ToBytes(&keyImageBytes) keyImagePoint.ToBytes(&keyImage)
keyImageGe := new(ExtendedGroupElement) keyImageGe := new(ExtendedGroupElement)
keyImageGe.FromBytes(&keyImageBytes) keyImageGe.FromBytes(&keyImage)
keyImage = PubKey(keyImageBytes)
var keyImagePre [8]CachedGroupElement var keyImagePre [8]CachedGroupElement
GePrecompute(&keyImagePre, keyImageGe) GePrecompute(&keyImagePre, keyImageGe)
k := RandomScalar() k := RandomScalar()
pubKeys = make([]PubKey, len(mixins)+1) pubKeys = make([]Key, len(mixins)+1)
privIndex := rand.Intn(len(pubKeys)) privIndex := rand.Intn(len(pubKeys))
pubKeys[privIndex] = *privKey.PubKey() pubKeys[privIndex] = *privKey.PubKey()
r := make([]*RingSignatureElement, len(pubKeys)) r := make([]*RingSignatureElement, len(pubKeys))
var sum [ScalarLength]byte sum := new(Key)
toHash := prefixHash[:] toHash := prefixHash[:]
for i := 0; i < len(pubKeys); i++ { for i := 0; i < len(pubKeys); i++ {
tmpE := new(ExtendedGroupElement) tmpE := new(ExtendedGroupElement)
tmpP := new(ProjectiveGroupElement) tmpP := new(ProjectiveGroupElement)
var tmpEBytes, tmpPBytes [PointLength]byte var tmpEBytes, tmpPBytes Key
if i == privIndex { if i == privIndex {
GeScalarMultBase(tmpE, &k) GeScalarMultBase(tmpE, k)
tmpE.ToBytes(&tmpEBytes) tmpE.ToBytes(&tmpEBytes)
toHash = append(toHash, tmpEBytes[:]...) toHash = append(toHash, tmpEBytes[:]...)
tmpE = privKey.PubKey().HashToEC() tmpE = privKey.PubKey().HashToEC()
GeScalarMult(tmpP, &k, tmpE) GeScalarMult(tmpP, k, tmpE)
tmpP.ToBytes(&tmpPBytes) tmpP.ToBytes(&tmpPBytes)
toHash = append(toHash, tmpPBytes[:]...) toHash = append(toHash, tmpPBytes[:]...)
} else { } else {
@ -119,64 +125,60 @@ func CreateSignature(prefixHash *Hash, mixins []PubKey, privKey *PrivKey) (keyIm
c: RandomScalar(), c: RandomScalar(),
r: RandomScalar(), r: RandomScalar(),
} }
pubKeyBytes := pubKeys[i].ToBytes() tmpE.FromBytes(&pubKeys[i])
tmpE.FromBytes(&pubKeyBytes) GeDoubleScalarMultVartime(tmpP, r[i].c, tmpE, r[i].r)
GeDoubleScalarMultVartime(tmpP, &r[i].c, tmpE, &r[i].r)
tmpP.ToBytes(&tmpPBytes) tmpP.ToBytes(&tmpPBytes)
toHash = append(toHash, tmpPBytes[:]...) toHash = append(toHash, tmpPBytes[:]...)
tmpE = pubKeys[i].HashToEC() tmpE = pubKeys[i].HashToEC()
GeDoubleScalarMultPrecompVartime(tmpP, &r[i].r, tmpE, &r[i].c, &keyImagePre) GeDoubleScalarMultPrecompVartime(tmpP, r[i].r, tmpE, r[i].c, &keyImagePre)
tmpP.ToBytes(&tmpPBytes) tmpP.ToBytes(&tmpPBytes)
toHash = append(toHash, tmpPBytes[:]...) toHash = append(toHash, tmpPBytes[:]...)
ScAdd(&sum, &sum, &r[i].c) ScAdd(sum, sum, r[i].c)
} }
} }
h := HashToScalar(toHash) h := HashToScalar(toHash)
r[privIndex] = new(RingSignatureElement) r[privIndex] = NewRingSignatureElement()
ScSub(&r[privIndex].c, &h, &sum) ScSub(r[privIndex].c, h, sum)
scalar := privKey.ToBytes() ScMulSub(r[privIndex].r, r[privIndex].c, privKey, k)
ScMulSub(&r[privIndex].r, &r[privIndex].c, &scalar, &k)
sig = r sig = r
return return
} }
func VerifySignature(prefixHash *Hash, keyImage *PubKey, pubKeys []PubKey, ringSignature RingSignature) (result bool) { func VerifySignature(prefixHash *Hash, keyImage *Key, pubKeys []Key, ringSignature RingSignature) (result bool) {
keyImageGe := new(ExtendedGroupElement) keyImageGe := new(ExtendedGroupElement)
keyImageBytes := [PointLength]byte(*keyImage) if !keyImageGe.FromBytes(keyImage) {
if !keyImageGe.FromBytes(&keyImageBytes) {
result = false result = false
return return
} }
var keyImagePre [8]CachedGroupElement var keyImagePre [8]CachedGroupElement
GePrecompute(&keyImagePre, keyImageGe) GePrecompute(&keyImagePre, keyImageGe)
toHash := prefixHash[:] toHash := prefixHash[:]
var tmpS, sum [ScalarLength]byte tmpS, sum := new(Key), new(Key)
for i, pubKey := range pubKeys { for i, pubKey := range pubKeys {
rse := ringSignature[i] rse := ringSignature[i]
if !ScValid(&rse.c) || !ScValid(&rse.r) { if !ScValid(rse.c) || !ScValid(rse.r) {
result = false result = false
return return
} }
tmpE := new(ExtendedGroupElement) tmpE := new(ExtendedGroupElement)
tmpP := new(ProjectiveGroupElement) tmpP := new(ProjectiveGroupElement)
pubKeyBytes := [PointLength]byte(pubKey) if !tmpE.FromBytes(&pubKey) {
if !tmpE.FromBytes(&pubKeyBytes) {
result = false result = false
return return
} }
var tmpPBytes, tmpEBytes [PointLength]byte var tmpPBytes, tmpEBytes Key
GeDoubleScalarMultVartime(tmpP, &rse.c, tmpE, &rse.r) GeDoubleScalarMultVartime(tmpP, rse.c, tmpE, rse.r)
tmpP.ToBytes(&tmpPBytes) tmpP.ToBytes(&tmpPBytes)
toHash = append(toHash, tmpPBytes[:]...) toHash = append(toHash, tmpPBytes[:]...)
tmpE = pubKey.HashToEC() tmpE = pubKey.HashToEC()
tmpE.ToBytes(&tmpEBytes) tmpE.ToBytes(&tmpEBytes)
GeDoubleScalarMultPrecompVartime(tmpP, &rse.r, tmpE, &rse.c, &keyImagePre) GeDoubleScalarMultPrecompVartime(tmpP, rse.r, tmpE, rse.c, &keyImagePre)
tmpP.ToBytes(&tmpPBytes) tmpP.ToBytes(&tmpPBytes)
toHash = append(toHash, tmpPBytes[:]...) toHash = append(toHash, tmpPBytes[:]...)
ScAdd(&sum, &sum, &rse.c) ScAdd(sum, sum, rse.c)
} }
tmpS = HashToScalar(toHash) tmpS = HashToScalar(toHash)
ScSub(&sum, &tmpS, &sum) ScSub(sum, tmpS, sum)
result = ScIsZero(&sum) result = ScIsZero(sum)
return return
} }

View file

@ -759,9 +759,9 @@ func TestHashToScalar(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
toHash, _ := hex.DecodeString(test.hashHex) toHash, _ := hex.DecodeString(test.hashHex)
want := HexToBytes(test.scalarHex) want := HexToKey(test.scalarHex)
got := HashToScalar(toHash) got := HashToScalar(toHash)
if want != got { if want != *got {
t.Errorf("%x, want %x, got %x", toHash, want, got) t.Errorf("%x, want %x, got %x", toHash, want, got)
} }
} }
@ -1798,12 +1798,12 @@ func TestHashToEC(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
pubkeyBytes := HexToBytes(test.pubkeyHex) pubkeyBytes := HexToKey(test.pubkeyHex)
pubKey := new(PubKey) pubKey := new(Key)
pubKey.FromBytes(pubkeyBytes) pubKey.FromBytes(pubkeyBytes)
want := HexToBytes(test.extendedHex) want := HexToKey(test.extendedHex)
ecPoint := pubKey.HashToEC() ecPoint := pubKey.HashToEC()
var got [32]byte var got Key
ecPoint.ToBytes(&got) ecPoint.ToBytes(&got)
if want != got { if want != got {
t.Errorf("%x: want %x, got %x", pubkeyBytes, want, got) t.Errorf("%x: want %x, got %x", pubkeyBytes, want, got)
@ -1815,9 +1815,9 @@ func TestCreateSignature(t *testing.T) {
numTries := 50 numTries := 50
numMixins := 10 numMixins := 10
for i := 0; i < numTries; i++ { for i := 0; i < numTries; i++ {
hash := Hash(RandomScalar()) hash := Hash(*RandomScalar())
privKey, _ := NewKeyPair() privKey, _ := NewKeyPair()
mixins := make([]PubKey, numMixins) mixins := make([]Key, numMixins)
for j := 0; j < numMixins; j++ { for j := 0; j < numMixins; j++ {
_, pk := NewKeyPair() _, pk := NewKeyPair()
mixins[j] = *pk mixins[j] = *pk

View file

@ -40763,11 +40763,11 @@ func TestVerifySignature(t *testing.T) {
}, },
} }
for j, test := range tests { for j, test := range tests {
prefixHash := Hash(HexToBytes(test.prefixHashHex)) prefixHash := HexToHash(test.prefixHashHex)
keyImage := PubKey(HexToBytes(test.keyImageHex)) keyImage := HexToKey(test.keyImageHex)
pubKeys := make([]PubKey, len(test.pubKeys)) pubKeys := make([]Key, len(test.pubKeys))
for i, pubKeyHex := range test.pubKeys { for i, pubKeyHex := range test.pubKeys {
pubKeys[i] = PubKey(HexToBytes(pubKeyHex)) pubKeys[i] = HexToKey(pubKeyHex)
} }
ringSignature := make([]*RingSignatureElement, len(test.pubKeys)) ringSignature := make([]*RingSignatureElement, len(test.pubKeys))
ringSignatureBytes, _ := hex.DecodeString(test.ringSignature) ringSignatureBytes, _ := hex.DecodeString(test.ringSignature)

View file

@ -18,7 +18,7 @@ const (
var UnimplementedError = fmt.Errorf("Unimplemented") var UnimplementedError = fmt.Errorf("Unimplemented")
type txOutToScript struct { type txOutToScript struct {
pubKeys []PubKey pubKeys []Key
script []byte script []byte
} }
@ -27,7 +27,7 @@ type txOutToScriptHash struct {
} }
type txOutToKey struct { type txOutToKey struct {
key PubKey key Key
} }
type TxOutTargetSerializer interface { type TxOutTargetSerializer interface {
@ -55,7 +55,7 @@ type txInToScriptHash struct {
type txInToKey struct { type txInToKey struct {
amount uint64 amount uint64
keyOffsets []uint64 keyOffsets []uint64
keyImage PubKey keyImage Key
} }
type TxInSerializer interface { type TxInSerializer interface {
@ -87,7 +87,7 @@ func (h *Hash) Serialize() (result []byte) {
return return
} }
func (p *PubKey) Serialize() (result []byte) { func (p *Key) Serialize() (result []byte) {
result = p[:] result = p[:]
return return
} }
@ -281,12 +281,12 @@ func ParseTxInToKey(buf io.Reader) (txIn *txInToKey, err error) {
return return
} }
} }
pubKey := make([]byte, PointLength) pubKey := make([]byte, KeyLength)
n, err := buf.Read(pubKey) n, err := buf.Read(pubKey)
if err != nil { if err != nil {
return return
} }
if n != PointLength { if n != KeyLength {
err = fmt.Errorf("Buffer not long enough for public key") err = fmt.Errorf("Buffer not long enough for public key")
return return
} }
@ -330,12 +330,12 @@ func ParseTxOutToScriptHash(buf io.Reader) (txOutTarget *txOutToScriptHash, err
func ParseTxOutToKey(buf io.Reader) (txOutTarget *txOutToKey, err error) { func ParseTxOutToKey(buf io.Reader) (txOutTarget *txOutToKey, err error) {
t := new(txOutToKey) t := new(txOutToKey)
pubKey := make([]byte, PointLength) pubKey := make([]byte, KeyLength)
n, err := buf.Read(pubKey) n, err := buf.Read(pubKey)
if err != nil { if err != nil {
return return
} }
if n != PointLength { if n != KeyLength {
err = fmt.Errorf("Buffer not long enough for public key") err = fmt.Errorf("Buffer not long enough for public key")
return return
} }

View file

@ -113,7 +113,7 @@ func TestCoinbaseTransaction(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("%s: error parsing tx: %s", test.name, err) t.Errorf("%s: error parsing tx: %s", test.name, err)
} }
wantHash := HexToBytes(test.hashHex) wantHash := HexToHash(test.hashHex)
gotHash := transaction.GetHash() gotHash := transaction.GetHash()
if wantHash != gotHash { if wantHash != gotHash {
t.Errorf("%s: want %x, got %x", test.name, wantHash, gotHash) t.Errorf("%s: want %x, got %x", test.name, wantHash, gotHash)
@ -331,13 +331,13 @@ func TestTransaction(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("%s: error parsing tx: %s", test.name, err) t.Errorf("%s: error parsing tx: %s", test.name, err)
} }
wantHash := HexToBytes(test.hashHex) wantHash := HexToHash(test.hashHex)
gotHash := transaction.GetHash() gotHash := transaction.GetHash()
if wantHash != gotHash { if wantHash != gotHash {
t.Errorf("%s: want %x, got %x", test.name, wantHash, gotHash) t.Errorf("%s: want %x, got %x", test.name, wantHash, gotHash)
} }
gotHash = transaction.PrefixHash() gotHash = transaction.PrefixHash()
wantHash = HexToBytes(test.prefixHashHex) wantHash = HexToHash(test.prefixHashHex)
if wantHash != gotHash { if wantHash != gotHash {
t.Errorf("%s: want %x, got %x", test.name, wantHash, gotHash) t.Errorf("%s: want %x, got %x", test.name, wantHash, gotHash)
} }