Skip to content

Commit d0e1583

Browse files
crypto/internal/fips140/edwards25519/field: speed up Element.Bytes
Write bytes in 64-bit chunks made from adjacent limbs. goos: linux goarch: amd64 pkg: crypto/internal/fips140/edwards25519/field cpu: Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz │ HEAD~1 │ HEAD │ │ sec/op │ sec/op vs base │ Bytes-8 76.14n ± 3% 13.61n ± 3% -82.13% (p=0.000 n=10) │ HEAD~1 │ HEAD │ │ B/op │ B/op vs base │ Bytes-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ¹ all samples are equal │ HEAD~1 │ HEAD │ │ allocs/op │ allocs/op vs base │ Bytes-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ¹ all samples are equal
1 parent e7d8573 commit d0e1583

1 file changed

Lines changed: 16 additions & 12 deletions

File tree

  • src/crypto/internal/fips140/edwards25519/field

src/crypto/internal/fips140/edwards25519/field/fe.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -233,18 +233,22 @@ func (v *Element) bytes(out *[32]byte) []byte {
233233
t := *v
234234
t.reduce()
235235

236-
var buf [8]byte
237-
for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
238-
bitsOffset := i * 51
239-
byteorder.LEPutUint64(buf[:], l<<uint(bitsOffset%8))
240-
for i, bb := range buf {
241-
off := bitsOffset/8 + i
242-
if off >= len(out) {
243-
break
244-
}
245-
out[off] |= bb
246-
}
247-
}
236+
// Pack five 51-bit limbs into four 64-bit words:
237+
//
238+
// 255 204 153 102 51 0
239+
// ├──l4──┼──l3──┼──l2──┼──l1──┼──l0──┤
240+
// ├───u3───┼───u2───┼───u1───┼───u0───┤
241+
// 256 192 128 64 0
242+
243+
u0 := t.l1<<51 | t.l0
244+
u1 := t.l2<<(102-64) | t.l1>>(64-51)
245+
u2 := t.l3<<(153-128) | t.l2>>(128-102)
246+
u3 := t.l4<<(204-192) | t.l3>>(192-153)
247+
248+
byteorder.LEPutUint64(out[0*8:], u0)
249+
byteorder.LEPutUint64(out[1*8:], u1)
250+
byteorder.LEPutUint64(out[2*8:], u2)
251+
byteorder.LEPutUint64(out[3*8:], u3)
248252

249253
return out[:]
250254
}

0 commit comments

Comments
 (0)