| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- // Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be found in
- // the LICENSE file.
- //go:build !gofuzz && cgo
- // +build !gofuzz,cgo
- package secp256k1
- import (
- "math/big"
- "unsafe"
- )
- /*
- #include "libsecp256k1/include/secp256k1.h"
- extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar);
- */
- import "C"
- func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
- // Ensure scalar is exactly 32 bytes. We pad always, even if
- // scalar is 32 bytes long, to avoid a timing side channel.
- if len(scalar) > 32 {
- panic("can't handle scalars > 256 bits")
- }
- // NOTE: potential timing issue
- padded := make([]byte, 32)
- copy(padded[32-len(scalar):], scalar)
- scalar = padded
- // Do the multiplication in C, updating point.
- point := make([]byte, 64)
- readBits(Bx, point[:32])
- readBits(By, point[32:])
- pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
- scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
- res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
- // Unpack the result and clear temporaries.
- x := new(big.Int).SetBytes(point[:32])
- y := new(big.Int).SetBytes(point[32:])
- for i := range point {
- point[i] = 0
- }
- for i := range padded {
- scalar[i] = 0
- }
- if res != 1 {
- return nil, nil
- }
- return x, y
- }
|