From 47680d04461d871f17065eaaf11bfe4552335c41 Mon Sep 17 00:00:00 2001 From: hopehook Date: Wed, 3 Aug 2022 13:31:10 +0800 Subject: [PATCH] cryptobyte: add ReadUint64 and AddUint64 Fixes golang/go#53481. Change-Id: Ic00eef498d1d3b5b0ca5c9c526fac7c26de30cf2 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/421014 TryBot-Result: Gopher Robot Auto-Submit: Filippo Valsorda Run-TryBot: hopehook Reviewed-by: Damien Neil Reviewed-by: Roland Shoemaker --- cryptobyte/builder.go | 5 +++++ cryptobyte/cryptobyte_test.go | 24 ++++++++++++++++++++++-- cryptobyte/string.go | 11 +++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/cryptobyte/builder.go b/cryptobyte/builder.go index c7ded75771..2a90c592d7 100644 --- a/cryptobyte/builder.go +++ b/cryptobyte/builder.go @@ -95,6 +95,11 @@ func (b *Builder) AddUint32(v uint32) { b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) } +// AddUint64 appends a big-endian, 64-bit value to the byte string. +func (b *Builder) AddUint64(v uint64) { + b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v)) +} + // AddBytes appends a sequence of bytes to the byte string. func (b *Builder) AddBytes(v []byte) { b.add(v...) diff --git a/cryptobyte/cryptobyte_test.go b/cryptobyte/cryptobyte_test.go index fb63709148..dc90e81fa9 100644 --- a/cryptobyte/cryptobyte_test.go +++ b/cryptobyte/cryptobyte_test.go @@ -141,7 +141,7 @@ func TestUint24(t *testing.T) { var s String = b.BytesOrPanic() var v uint32 if !s.ReadUint24(&v) { - t.Error("ReadUint8() = false, want true") + t.Error("ReadUint24() = false, want true") } if v != 0xfffefd { t.Errorf("v = %d, want fffefd", v) @@ -169,7 +169,7 @@ func TestUint32(t *testing.T) { var s String = b.BytesOrPanic() var v uint32 if !s.ReadUint32(&v) { - t.Error("ReadUint8() = false, want true") + t.Error("ReadUint32() = false, want true") } if v != 0xfffefdfc { t.Errorf("v = %x, want fffefdfc", v) @@ -179,6 +179,26 @@ func TestUint32(t *testing.T) { } } +func TestUint64(t *testing.T) { + var b Builder + b.AddUint64(0xf2fefefcff3cfdfc) + if err := builderBytesEq(&b, 242, 254, 254, 252, 255, 60, 253, 252); err != nil { + t.Error(err) + } + + var s String = b.BytesOrPanic() + var v uint64 + if !s.ReadUint64(&v) { + t.Error("ReadUint64() = false, want true") + } + if v != 0xf2fefefcff3cfdfc { + t.Errorf("v = %x, want f2fefefcff3cfdfc", v) + } + if len(s) != 0 { + t.Errorf("len(s) = %d, want 0", len(s)) + } +} + func TestUMultiple(t *testing.T) { var b Builder b.AddUint8(23) diff --git a/cryptobyte/string.go b/cryptobyte/string.go index 589d297e6b..0531a3d6f1 100644 --- a/cryptobyte/string.go +++ b/cryptobyte/string.go @@ -81,6 +81,17 @@ func (s *String) ReadUint32(out *uint32) bool { return true } +// ReadUint64 decodes a big-endian, 64-bit value into out and advances over it. +// It reports whether the read was successful. +func (s *String) ReadUint64(out *uint64) bool { + v := s.read(8) + if v == nil { + return false + } + *out = uint64(v[0])<<56 | uint64(v[1])<<48 | uint64(v[2])<<40 | uint64(v[3])<<32 | uint64(v[4])<<24 | uint64(v[5])<<16 | uint64(v[6])<<8 | uint64(v[7]) + return true +} + func (s *String) readUnsigned(out *uint32, length int) bool { v := s.read(length) if v == nil {