github.com/luckypickle/go-ethereum-vet@v1.14.2/crypto/secp256k1/scalar_mult_cgo.go (about) 1 // Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 //go:build !gofuzz && cgo 6 // +build !gofuzz,cgo 7 8 package secp256k1 9 10 import ( 11 "math/big" 12 "unsafe" 13 ) 14 15 /* 16 17 #include "libsecp256k1/include/secp256k1.h" 18 19 extern int vet_secp256k1_ext_scalar_mul(const vet_secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar); 20 21 */ 22 import "C" 23 24 func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { 25 // Ensure scalar is exactly 32 bytes. We pad always, even if 26 // scalar is 32 bytes long, to avoid a timing side channel. 27 if len(scalar) > 32 { 28 panic("can't handle scalars > 256 bits") 29 } 30 // NOTE: potential timing issue 31 padded := make([]byte, 32) 32 copy(padded[32-len(scalar):], scalar) 33 scalar = padded 34 35 // Do the multiplication in C, updating point. 36 point := make([]byte, 64) 37 readBits(Bx, point[:32]) 38 readBits(By, point[32:]) 39 40 pointPtr := (*C.uchar)(unsafe.Pointer(&point[0])) 41 scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0])) 42 res := C.vet_secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr) 43 44 // Unpack the result and clear temporaries. 45 x := new(big.Int).SetBytes(point[:32]) 46 y := new(big.Int).SetBytes(point[32:]) 47 for i := range point { 48 point[i] = 0 49 } 50 for i := range padded { 51 scalar[i] = 0 52 } 53 if res != 1 { 54 return nil, nil 55 } 56 return x, y 57 }