crypto

package
v0.5.0-rc8-hotfix1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 7, 2019 License: Apache-2.0 Imports: 8 Imported by: 8

README

CGO Binding Guide

Software Requirement

  • CMAKE (Version at least 3.10.2)
    • Install on MacOS:
      brew install cmake
    
    • Install on Linux:
      wget http://www.cmake.org/files/v3.11/cmake-3.11.0-Linux-x86_64.tar.gz
      tar -xvf cmake-3.11.0-Linux-x86_64.tar.gz
      cd cmake-3.11.0-Linux-x86_64
      sudo  cp -r bin /usr/
      sudo  cp -r share /usr/
      sudo  cp -r doc /usr/share/
      sudo  cp -r man /usr/share/
    

CGO Development Guide

1. Declare the use of CGO and files binding
 //#include "lib/ecckey.h"
 //#include "lib/ecckey.c"
 import “C”
  • Just use import “C” to start using CGO. It comes with Go. No need to install any other library.
  • “//” is not a regular comment sign in CGO declaration. It starts a directive and will not be ignored by compiler.
  • import “C” should be immediately preceded by //#include XXX or //#cgo.
  • //#include XXX indicates the use of c header files and c source code files
  • //#cgo is used to indicate the use of flags like CFLAGS, CPPFLAGS, CXXFLAGS, FFLAGS and LDFLAGS etc. to tweak the behavior of C, C++ compiler. The //#cgo directive can also include a list of build constraints that limit the os and architecture. It can also indicates the C library, so that you do not have to include the source code files.
//#cgo darwin LDFLAGS: -L${SRCDIR}/lib -lsect283k1_macos
//#cgo linux LDFLAGS: -L${SRCDIR}/lib -lsect283k1_ubuntu

This indicates the library sect283k1_macos will be used in Mac platform,
sect283k1_ubuntu in Linux platform. Both of them are located in directory ${SRCDIR}/lib. -L specifies the location of the library.

package crypto

//#include "lib/ecckey.h"
//#include "lib/ecdsa.h"
//#include "lib/sect283k1.h"
//#cgo darwin LDFLAGS: -L${SRCDIR}/lib -lsect283k1_macos
//#cgo linux LDFLAGS: -L${SRCDIR}/lib -lsect283k1_ubuntu
import "C"
import (
    "bytes"
    "encoding/binary"
    "errors"

    "github.com/iotexproject/iotex-core/pkg/enc"
    "github.com/iotexproject/iotex-core/pkg/keypair"
)
2. Go references C
  • Go calls C functions: Just call C.function_name_in_C(…)
  • Go uses any type in C: C.type_in_C, like C.uint32_t, C.ec_point_aff_twist
  • Pointer pass in CGO is the same as in go
  • Go can access any fields of C struct in the same way in Go struct
    // C header file
    
    typedef struct
    {
        uint32_t d[9];         
        ec283_point_lambda_aff Q;
    }ec283_key_pair;
    
    void keypair_generation(ec283_key_pair *key);
    
    // Go file
    func (c *ec283) NewKeyPair() (keypair.PublicKey, keypair.PrivateKey, error) {
        var kp C.ec283_key_pair
        C.keypair_generation(&kp)
        pubKey := kp.Q
        privKey := kp.d
        ...
    }
    
  • Primitive type conversion: Just cast the type from C type to Go or from Go to C
    // privkey has go type elements, privkeySer has C type elements
    for i := 0; i < privkeySize; i++ {
        privkeySer[i] = (C.uint32_t)(privkey[i])
    }
    
    // sigSer has C type elements, sig has go type elements
    for i, x := range sigSer {
        sig[i] = (uint32)(x)
    }
    
3. Go passes an array to C

Just pass the first element of the slice as a pointer, and cast the pointer to C corresponding
type. The slice in Go is a struct including header and elements, so &slice won’t give you the
first element.

// C file
// d and sig are arrays

uint32_t BLS_sign(uint32_t *d, const uint8_t *msg, uint64_t mlen, uint32_t *sig);

// Go file
// Sign signs a message given a private key

func (b *bls) Sign(privkey []uint32, msg []byte) (bool, []byte, error) {
    var sigSer [sigSize]C.uint32_t
    msgString := string(msg[:])

    if ok := C.BLS_sign((*C.uint32_t)(unsafe.Pointer(&privkey[0])), (*C.uint8_t)(&msg[0]), (C.uint64_t)(len(msgString)), &sigSer[0]); ok == 1 {
        sig, err := b.signatureSerialization(sigSer)
        if err != nil {
            return false, []byte{}, err
        }
        return true, sig, nil
    }
    return false, []byte{}, ErrSignError
}

4. Use struct defined in C
  • Construct a corresponding struct in Go that mimics the same struct in C.
  • (Recommended) Write function to serialize and deserialize the the struct, so the information can be exposed outside independently.
    // C header file and C struct definition
    typedef struct
    {
        uint32_t x[9];     
        uint32_t l[9];     
    }ec283_point_lambda_aff;
    
    // Go file
    
    func (*ec283) publicKeySerialization(pubKey C.ec283_point_lambda_aff) (keypair.PublicKey, error) {
        var xl [18]uint32
        for i := 0; i < 9; i++ {
            xl[i] = (uint32)(pubKey.x[i])
            xl[i+9] = (uint32)(pubKey.l[i])
        }
        buf := new(bytes.Buffer)
        err := binary.Write(buf, enc.MachineEndian, xl)
        if err != nil {
            return keypair.ZeroPublicKey, err
        }
        return keypair.BytesToPublicKey(buf.Bytes())
    }
    
    func (*ec283) publicKeyDeserialization(pubKey keypair.PublicKey) (C.ec283_point_lambda_aff, error) {
        var xl [18]uint32
        var pub C.ec283_point_lambda_aff
        rbuf := bytes.NewReader(pubKey[:])
        err := binary.Read(rbuf, enc.MachineEndian, &xl)
        if err != nil {
            return pub, err
        }
        for i := 0; i < 9; i++ {
            pub.x[i] = (C.uint32_t)(xl[i])
            pub.l[i] = (C.uint32_t)(xl[i+9])
        }
        return pub, nil
    }
    

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// CryptoSeed is a hardcoded seed that will be replaced by a seed produced dynamically.
	CryptoSeed = []byte{0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef}
)
View Source
var EC283 ec283

EC283 represents an ec283 struct singleton that contains the set of cryptography functions based on the elliptic curve 283. It is used for blockchain address creation, action and block signature and verification.

Functions

func Sort added in v0.2.0

func Sort(hashes [][]byte, nonce uint64)

Sort sorts a given slices of hashes cryptographically using hash function

func SortCandidates added in v0.3.0

func SortCandidates(candidates []string, epochNum uint64, cryptoSeed []byte)

SortCandidates sorts a given slices of hashes cryptographically using hash function

Types

type Merkle

type Merkle struct {
	// contains filtered or unexported fields
}

Merkle tree struct

func NewMerkleTree

func NewMerkleTree(leaves []hash.Hash256) *Merkle

NewMerkleTree creates a merkle tree given hashed leaves

func (*Merkle) HashTree

func (mk *Merkle) HashTree() hash.Hash256

HashTree calculates the root hash of a merkle tree

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL