mirror of
https://github.com/golang/go
synced 2024-11-11 18:21:40 -07:00
crypto/x509,math/rand/v2: implement the encoding.(Binary|Text)Appender
Implement the encoding.(Binary|Text)Appender interfaces for "x509.OID". Implement the encoding.BinaryAppender interface for "rand/v2.PCG" and "rand/v2.ChaCha8". "rand/v2.ChaCha8.MarshalBinary" alse gains some performance benefits: │ old │ new │ │ sec/op │ sec/op vs base │ ChaCha8MarshalBinary-8 33.730n ± 2% 9.786n ± 1% -70.99% (p=0.000 n=10) ChaCha8MarshalBinaryRead-8 99.86n ± 1% 17.79n ± 0% -82.18% (p=0.000 n=10) geomean 58.04n 13.19n -77.27% │ old │ new │ │ B/op │ B/op vs base │ ChaCha8MarshalBinary-8 48.00 ± 0% 0.00 ± 0% -100.00% (p=0.000 n=10) ChaCha8MarshalBinaryRead-8 83.00 ± 0% 0.00 ± 0% -100.00% (p=0.000 n=10) │ old │ new │ │ allocs/op │ allocs/op vs base │ ChaCha8MarshalBinary-8 1.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10) ChaCha8MarshalBinaryRead-8 2.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=10) For #62384
This commit is contained in:
parent
f38d42f2c4
commit
78abf9c5df
@ -11,3 +11,7 @@ pkg math/big, method (*Rat) AppendText([]uint8) ([]uint8, error) #62384
|
|||||||
pkg regexp, method (*Regexp) AppendText([]uint8) ([]uint8, error) #62384
|
pkg regexp, method (*Regexp) AppendText([]uint8) ([]uint8, error) #62384
|
||||||
pkg time, method (Time) AppendBinary([]uint8) ([]uint8, error) #62384
|
pkg time, method (Time) AppendBinary([]uint8) ([]uint8, error) #62384
|
||||||
pkg time, method (Time) AppendText([]uint8) ([]uint8, error) #62384
|
pkg time, method (Time) AppendText([]uint8) ([]uint8, error) #62384
|
||||||
|
pkg math/rand/v2, method (*ChaCha8) AppendBinary([]uint8) ([]uint8, error) #62384
|
||||||
|
pkg math/rand/v2, method (*PCG) AppendBinary([]uint8) ([]uint8, error) #62384
|
||||||
|
pkg crypto/x509, method (OID) AppendBinary([]uint8) ([]uint8, error) #62384
|
||||||
|
pkg crypto/x509, method (OID) AppendText([]uint8) ([]uint8, error) #62384
|
||||||
|
2
doc/next/6-stdlib/99-minor/crypto/x509/62384.md
Normal file
2
doc/next/6-stdlib/99-minor/crypto/x509/62384.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[OID] now implements the [encoding.BinaryAppender] and [encoding.TextAppender]
|
||||||
|
interfaces.
|
1
doc/next/6-stdlib/99-minor/math/rand/v2/62384.md
Normal file
1
doc/next/6-stdlib/99-minor/math/rand/v2/62384.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
[ChaCha8] and [PCG] now implement the [encoding.BinaryAppender] interface.
|
@ -112,9 +112,14 @@ func appendBase128BigInt(dst []byte, n *big.Int) []byte {
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendText implements [encoding.TextAppender]
|
||||||
|
func (o OID) AppendText(b []byte) ([]byte, error) {
|
||||||
|
return append(b, o.String()...), nil
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalText implements [encoding.TextMarshaler]
|
// MarshalText implements [encoding.TextMarshaler]
|
||||||
func (o OID) MarshalText() ([]byte, error) {
|
func (o OID) MarshalText() ([]byte, error) {
|
||||||
return []byte(o.String()), nil
|
return o.AppendText(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalText implements [encoding.TextUnmarshaler]
|
// UnmarshalText implements [encoding.TextUnmarshaler]
|
||||||
@ -180,9 +185,14 @@ func (o *OID) unmarshalOIDText(oid string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendBinary implements [encoding.BinaryAppender]
|
||||||
|
func (o OID) AppendBinary(b []byte) ([]byte, error) {
|
||||||
|
return append(b, o.der...), nil
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalBinary implements [encoding.BinaryMarshaler]
|
// MarshalBinary implements [encoding.BinaryMarshaler]
|
||||||
func (o OID) MarshalBinary() ([]byte, error) {
|
func (o OID) MarshalBinary() ([]byte, error) {
|
||||||
return bytes.Clone(o.der), nil
|
return o.AppendBinary(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalBinary implements [encoding.BinaryUnmarshaler]
|
// UnmarshalBinary implements [encoding.BinaryUnmarshaler]
|
||||||
|
@ -228,6 +228,14 @@ func TestOIDMarshal(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textAppend := make([]byte, 4)
|
||||||
|
textAppend, err = o.AppendText(textAppend)
|
||||||
|
textAppend = textAppend[4:]
|
||||||
|
if string(textAppend) != tt.in || err != nil {
|
||||||
|
t.Errorf("(%#v).AppendText() = (%v, %v); want = (%v, nil)", o, string(textAppend), err, tt.in)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
binary, err := o.MarshalBinary()
|
binary, err := o.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("(%#v).MarshalBinary() = %v; want = nil", o, err)
|
t.Errorf("(%#v).MarshalBinary() = %v; want = nil", o, err)
|
||||||
@ -242,6 +250,23 @@ func TestOIDMarshal(t *testing.T) {
|
|||||||
t.Errorf("(*OID).UnmarshalBinary(%v) = %v; want = %v", binary, o3, tt.out)
|
t.Errorf("(*OID).UnmarshalBinary(%v) = %v; want = %v", binary, o3, tt.out)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binaryAppend := make([]byte, 4)
|
||||||
|
binaryAppend, err = o.AppendBinary(binaryAppend)
|
||||||
|
binaryAppend = binaryAppend[4:]
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("(%#v).AppendBinary() = %v; want = nil", o, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var o4 OID
|
||||||
|
if err := o4.UnmarshalBinary(binaryAppend); err != nil {
|
||||||
|
t.Errorf("(*OID).UnmarshalBinary(%v) = %v; want = nil", binaryAppend, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !o4.Equal(tt.out) {
|
||||||
|
t.Errorf("(*OID).UnmarshalBinary(%v) = %v; want = %v", binaryAppend, o4, tt.out)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ func (c *ChaCha8) Read(p []byte) (n int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
// UnmarshalBinary implements the [encoding.BinaryUnmarshaler] interface.
|
||||||
func (c *ChaCha8) UnmarshalBinary(data []byte) error {
|
func (c *ChaCha8) UnmarshalBinary(data []byte) error {
|
||||||
data, ok := cutPrefix(data, []byte("readbuf:"))
|
data, ok := cutPrefix(data, []byte("readbuf:"))
|
||||||
if ok {
|
if ok {
|
||||||
@ -98,13 +98,18 @@ func readUint8LengthPrefixed(b []byte) (buf, rest []byte, ok bool) {
|
|||||||
return b[1 : 1+b[0]], b[1+b[0]:], true
|
return b[1 : 1+b[0]], b[1+b[0]:], true
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
// AppendBinary implements the [encoding.BinaryAppender] interface.
|
||||||
func (c *ChaCha8) MarshalBinary() ([]byte, error) {
|
func (c *ChaCha8) AppendBinary(b []byte) ([]byte, error) {
|
||||||
if c.readLen > 0 {
|
if c.readLen > 0 {
|
||||||
out := []byte("readbuf:")
|
b = append(b, "readbuf:"...)
|
||||||
out = append(out, uint8(c.readLen))
|
b = append(b, uint8(c.readLen))
|
||||||
out = append(out, c.readBuf[len(c.readBuf)-c.readLen:]...)
|
b = append(b, c.readBuf[len(c.readBuf)-c.readLen:]...)
|
||||||
return append(out, chacha8rand.Marshal(&c.state)...), nil
|
|
||||||
}
|
}
|
||||||
return chacha8rand.Marshal(&c.state), nil
|
return append(b, chacha8rand.Marshal(&c.state)...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary implements the [encoding.BinaryMarshaler] interface.
|
||||||
|
func (c *ChaCha8) MarshalBinary() ([]byte, error) {
|
||||||
|
// the maximum length of (chacha8rand.Marshal + c.readBuf + "readbuf:") is 64
|
||||||
|
return c.AppendBinary(make([]byte, 0, 64))
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,22 @@ func TestChaCha8Read(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkChaCha8MarshalBinary(b *testing.B) {
|
||||||
|
p := NewChaCha8(chacha8seed)
|
||||||
|
for range b.N {
|
||||||
|
p.MarshalBinary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkChaCha8MarshalBinaryRead(b *testing.B) {
|
||||||
|
p := NewChaCha8(chacha8seed)
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
for range b.N {
|
||||||
|
p.MarshalBinary()
|
||||||
|
p.Read(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestChaCha8Marshal(t *testing.T) {
|
func TestChaCha8Marshal(t *testing.T) {
|
||||||
p := NewChaCha8(chacha8seed)
|
p := NewChaCha8(chacha8seed)
|
||||||
for i, x := range chacha8output {
|
for i, x := range chacha8output {
|
||||||
@ -108,6 +124,17 @@ func TestChaCha8Marshal(t *testing.T) {
|
|||||||
if string(enc) != chacha8marshal[i] {
|
if string(enc) != chacha8marshal[i] {
|
||||||
t.Errorf("#%d: MarshalBinary=%q, want %q", i, enc, chacha8marshal[i])
|
t.Errorf("#%d: MarshalBinary=%q, want %q", i, enc, chacha8marshal[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b := make([]byte, 4, 32)
|
||||||
|
b, err = p.AppendBinary(b)
|
||||||
|
encAppend := b[4:]
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("#%d: AppendBinary: %v", i, err)
|
||||||
|
}
|
||||||
|
if string(encAppend) != chacha8marshal[i] {
|
||||||
|
t.Errorf("#%d: AppendBinary=%q, want %q", i, encAppend, chacha8marshal[i])
|
||||||
|
}
|
||||||
|
|
||||||
*p = ChaCha8{}
|
*p = ChaCha8{}
|
||||||
if err := p.UnmarshalBinary(enc); err != nil {
|
if err := p.UnmarshalBinary(enc); err != nil {
|
||||||
t.Fatalf("#%d: UnmarshalBinary: %v", i, err)
|
t.Fatalf("#%d: UnmarshalBinary: %v", i, err)
|
||||||
@ -128,6 +155,17 @@ func TestChaCha8MarshalRead(t *testing.T) {
|
|||||||
if string(enc) != chacha8marshalread[i] {
|
if string(enc) != chacha8marshalread[i] {
|
||||||
t.Errorf("#%d: MarshalBinary=%q, want %q", i, enc, chacha8marshalread[i])
|
t.Errorf("#%d: MarshalBinary=%q, want %q", i, enc, chacha8marshalread[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b := make([]byte, 4, 32)
|
||||||
|
b, err = p.AppendBinary(b)
|
||||||
|
encAppend := b[4:]
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("#%d: AppendBinary: %v", i, err)
|
||||||
|
}
|
||||||
|
if string(encAppend) != chacha8marshalread[i] {
|
||||||
|
t.Errorf("#%d: AppendBinary=%q, want %q", i, encAppend, chacha8marshalread[i])
|
||||||
|
}
|
||||||
|
|
||||||
*p = ChaCha8{}
|
*p = ChaCha8{}
|
||||||
if err := p.UnmarshalBinary(enc); err != nil {
|
if err := p.UnmarshalBinary(enc); err != nil {
|
||||||
t.Fatalf("#%d: UnmarshalBinary: %v", i, err)
|
t.Fatalf("#%d: UnmarshalBinary: %v", i, err)
|
||||||
|
@ -31,18 +31,22 @@ func (p *PCG) Seed(seed1, seed2 uint64) {
|
|||||||
p.lo = seed2
|
p.lo = seed2
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalBinary implements the encoding.BinaryMarshaler interface.
|
// AppendBinary implements the [encoding.BinaryAppender] interface.
|
||||||
func (p *PCG) MarshalBinary() ([]byte, error) {
|
func (p *PCG) AppendBinary(b []byte) ([]byte, error) {
|
||||||
b := make([]byte, 20)
|
b = append(b, "pcg:"...)
|
||||||
copy(b, "pcg:")
|
b = byteorder.BeAppendUint64(b, p.hi)
|
||||||
byteorder.BePutUint64(b[4:], p.hi)
|
b = byteorder.BeAppendUint64(b, p.lo)
|
||||||
byteorder.BePutUint64(b[4+8:], p.lo)
|
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalBinary implements the [encoding.BinaryMarshaler] interface.
|
||||||
|
func (p *PCG) MarshalBinary() ([]byte, error) {
|
||||||
|
return p.AppendBinary(make([]byte, 0, 20))
|
||||||
|
}
|
||||||
|
|
||||||
var errUnmarshalPCG = errors.New("invalid PCG encoding")
|
var errUnmarshalPCG = errors.New("invalid PCG encoding")
|
||||||
|
|
||||||
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
|
// UnmarshalBinary implements the [encoding.BinaryUnmarshaler] interface.
|
||||||
func (p *PCG) UnmarshalBinary(data []byte) error {
|
func (p *PCG) UnmarshalBinary(data []byte) error {
|
||||||
if len(data) != 20 || string(data[:4]) != "pcg:" {
|
if len(data) != 20 || string(data[:4]) != "pcg:" {
|
||||||
return errUnmarshalPCG
|
return errUnmarshalPCG
|
||||||
|
@ -24,6 +24,7 @@ func TestPCGMarshal(t *testing.T) {
|
|||||||
seed1 = 0x123456789abcdef0
|
seed1 = 0x123456789abcdef0
|
||||||
seed2 = 0xfedcba9876543210
|
seed2 = 0xfedcba9876543210
|
||||||
want = "pcg:\x12\x34\x56\x78\x9a\xbc\xde\xf0\xfe\xdc\xba\x98\x76\x54\x32\x10"
|
want = "pcg:\x12\x34\x56\x78\x9a\xbc\xde\xf0\xfe\xdc\xba\x98\x76\x54\x32\x10"
|
||||||
|
wantAppend = "\x00\x00\x00\x00" + want
|
||||||
)
|
)
|
||||||
p.Seed(seed1, seed2)
|
p.Seed(seed1, seed2)
|
||||||
data, err := p.MarshalBinary()
|
data, err := p.MarshalBinary()
|
||||||
@ -31,6 +32,12 @@ func TestPCGMarshal(t *testing.T) {
|
|||||||
t.Errorf("MarshalBinary() = %q, %v, want %q, nil", data, err, want)
|
t.Errorf("MarshalBinary() = %q, %v, want %q, nil", data, err, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dataAppend := make([]byte, 4, 32)
|
||||||
|
dataAppend, err = p.AppendBinary(dataAppend)
|
||||||
|
if string(dataAppend) != wantAppend || err != nil {
|
||||||
|
t.Errorf("AppendBinary() = %q, %v, want %q, nil", dataAppend, err, wantAppend)
|
||||||
|
}
|
||||||
|
|
||||||
q := PCG{}
|
q := PCG{}
|
||||||
if err := q.UnmarshalBinary([]byte(want)); err != nil {
|
if err := q.UnmarshalBinary([]byte(want)); err != nil {
|
||||||
t.Fatalf("UnmarshalBinary(): %v", err)
|
t.Fatalf("UnmarshalBinary(): %v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user