mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.boringcrypto] crypto/internal/boring: avoid allocation in big.Int conversion
The conversion via byte slices is inefficient; we can convert via word slices and avoid the copy entirely. For #51940. Change-Id: I06f747e0acffffae427d9706d43bdacf146c027d Reviewed-on: https://go-review.googlesource.com/c/go/+/395875 Reviewed-by: Roland Shoemaker <roland@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
509776be5d
commit
3cb10d14b7
3 changed files with 21 additions and 7 deletions
|
|
@ -18,6 +18,8 @@ import (
|
||||||
"crypto/internal/boring/sig"
|
"crypto/internal/boring/sig"
|
||||||
_ "crypto/internal/boring/syso"
|
_ "crypto/internal/boring/syso"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"math/bits"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const available = true
|
const available = true
|
||||||
|
|
@ -58,15 +60,26 @@ type fail string
|
||||||
|
|
||||||
func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" }
|
func (e fail) Error() string { return "boringcrypto: " + string(e) + " failed" }
|
||||||
|
|
||||||
|
func wbase(b []big.Word) *C.uint8_t {
|
||||||
|
if len(b) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (*C.uint8_t)(unsafe.Pointer(&b[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
const wordBytes = bits.UintSize / 8
|
||||||
|
|
||||||
func bigToBN(x *big.Int) *C.GO_BIGNUM {
|
func bigToBN(x *big.Int) *C.GO_BIGNUM {
|
||||||
raw := x.Bytes()
|
raw := x.Bits()
|
||||||
return C._goboringcrypto_BN_bin2bn(base(raw), C.size_t(len(raw)), nil)
|
return C._goboringcrypto_BN_le2bn(wbase(raw), C.size_t(len(raw)*wordBytes), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func bnToBig(bn *C.GO_BIGNUM) *big.Int {
|
func bnToBig(bn *C.GO_BIGNUM) *big.Int {
|
||||||
raw := make([]byte, C._goboringcrypto_BN_num_bytes(bn))
|
raw := make([]big.Word, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes)
|
||||||
n := C._goboringcrypto_BN_bn2bin(bn, base(raw))
|
if C._goboringcrypto_BN_bn2le_padded(wbase(raw), C.size_t(len(raw)*wordBytes), bn) == 0 {
|
||||||
return new(big.Int).SetBytes(raw[:n])
|
panic("boringcrypto: bignum conversion failed")
|
||||||
|
}
|
||||||
|
return new(big.Int).SetBits(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func bigToBn(bnp **C.GO_BIGNUM, b *big.Int) bool {
|
func bigToBn(bnp **C.GO_BIGNUM, b *big.Int) bool {
|
||||||
|
|
@ -77,8 +90,7 @@ func bigToBn(bnp **C.GO_BIGNUM, b *big.Int) bool {
|
||||||
if b == nil {
|
if b == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
raw := b.Bytes()
|
bn := bigToBN(b)
|
||||||
bn := C._goboringcrypto_BN_bin2bn(base(raw), C.size_t(len(raw)), nil)
|
|
||||||
if bn == nil {
|
if bn == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,9 @@ unsigned _goboringcrypto_BN_num_bits(const GO_BIGNUM*);
|
||||||
unsigned _goboringcrypto_BN_num_bytes(const GO_BIGNUM*);
|
unsigned _goboringcrypto_BN_num_bytes(const GO_BIGNUM*);
|
||||||
int _goboringcrypto_BN_is_negative(const GO_BIGNUM*);
|
int _goboringcrypto_BN_is_negative(const GO_BIGNUM*);
|
||||||
GO_BIGNUM* _goboringcrypto_BN_bin2bn(const uint8_t*, size_t, GO_BIGNUM*);
|
GO_BIGNUM* _goboringcrypto_BN_bin2bn(const uint8_t*, size_t, GO_BIGNUM*);
|
||||||
|
GO_BIGNUM* _goboringcrypto_BN_le2bn(const uint8_t*, size_t, GO_BIGNUM*);
|
||||||
size_t _goboringcrypto_BN_bn2bin(const GO_BIGNUM*, uint8_t*);
|
size_t _goboringcrypto_BN_bn2bin(const GO_BIGNUM*, uint8_t*);
|
||||||
|
int _goboringcrypto_BN_bn2le_padded(uint8_t*, size_t, const GO_BIGNUM*);
|
||||||
|
|
||||||
// #include <openssl/ec.h>
|
// #include <openssl/ec.h>
|
||||||
/*unchecked (opaque)*/ typedef struct GO_EC_GROUP { char data[1]; } GO_EC_GROUP;
|
/*unchecked (opaque)*/ typedef struct GO_EC_GROUP { char data[1]; } GO_EC_GROUP;
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue