github.com/jiajun1992/watercarver@v0.0.0-20191031150618-dfc2b17c0c4a/go-ethereum/ctcrypto/shuffle/cgoBridge.go (about)

     1  package shuffle
     2  
     3  /*
     4  #include "GoApis.h"
     5  
     6  #cgo LDFLAGS: -L./ -lshuffle -Wl,-rpath=./
     7  */
     8  import "C"
     9  import (
    10  	"math/rand"
    11  	"reflect"
    12  	"unsafe"
    13  
    14  	crypto2 "github.com/ethereum/go-ethereum/ctcrypto/crypto"
    15  )
    16  
    17  func toSlice(cPtr, goPtr unsafe.Pointer, n int) {
    18  	sh := (*reflect.SliceHeader)(goPtr)
    19  	sh.Cap = n
    20  	sh.Len = n
    21  	sh.Data = uintptr(cPtr)
    22  }
    23  
    24  func eraseSlice(goPtr unsafe.Pointer) {
    25  	sh := (*reflect.SliceHeader)(goPtr)
    26  	sh.Cap = 0
    27  	sh.Len = 0
    28  	sh.Data = uintptr(0)
    29  }
    30  
    31  func Shuffle_gen(m, n int, inputs []crypto2.Key) (outputs []crypto2.Key, permutation []int, proof []byte) {
    32  	if m*n != len(inputs) {
    33  		return
    34  	}
    35  	_inputs := make([]byte, len(inputs)*crypto2.KeyLength)
    36  	for i := range inputs {
    37  		copy(_inputs[i*crypto2.KeyLength:(i+1)*crypto2.KeyLength], inputs[i][:])
    38  	}
    39  	var _outputs, _proof *C.char
    40  	var _permutation *C.int
    41  	var _outputsLen, _permutationLen, _proofLen int32
    42  	C.shuffle_gen((*C.char)(unsafe.Pointer(&_inputs[0])), (C.int)(m), (C.int)(n),
    43  		(**C.char)(unsafe.Pointer(&_outputs)), (*C.int)(unsafe.Pointer(&_outputsLen)),
    44  		(**C.int)(unsafe.Pointer(&_permutation)), (*C.int)(unsafe.Pointer(&_permutationLen)),
    45  		(**C.char)(unsafe.Pointer(&_proof)), (*C.int)(unsafe.Pointer(&_proofLen)))
    46  	if _outputs == nil || _proof == nil || _permutation == nil ||
    47  		_outputsLen == 0 || _permutationLen == 0 || _proofLen == 0 {
    48  		return
    49  	}
    50  	defer C.deleteCharArray(_outputs)
    51  	defer C.deleteIntArray(_permutation)
    52  	defer C.deleteCharArray(_proof)
    53  
    54  	var outputsSlice []byte // can only be used in this function, once getting outside, its data will be freed.
    55  	toSlice(unsafe.Pointer(_outputs), unsafe.Pointer(&outputsSlice), int(_outputsLen*crypto2.KeyLength))
    56  	defer eraseSlice(unsafe.Pointer(&outputsSlice))
    57  	outputs = make([]crypto2.Key, _outputsLen)
    58  	for i := range outputs {
    59  		copy(outputs[i][:], outputsSlice[i*crypto2.KeyLength:(i+1)*crypto2.KeyLength])
    60  	}
    61  
    62  	var permutationSlice []int32
    63  	toSlice(unsafe.Pointer(_permutation), unsafe.Pointer(&permutationSlice), int(_permutationLen))
    64  	defer eraseSlice(unsafe.Pointer(&permutationSlice))
    65  	permutation = make([]int, _permutationLen)
    66  	for i := range permutation {
    67  		permutation[i] = int(permutationSlice[i])
    68  	}
    69  
    70  	var proofSlice []byte
    71  	toSlice(unsafe.Pointer(_proof), unsafe.Pointer(&proofSlice), int(_proofLen))
    72  	defer eraseSlice(unsafe.Pointer(&proofSlice))
    73  	proof = make([]byte, _proofLen)
    74  	copy(proof, proofSlice[:])
    75  
    76  	return
    77  }
    78  
    79  func Gen_permutation(count int) []int32 {
    80  	permutation := make([]int32, count)
    81  	for i := range permutation {
    82  		permutation[i] = int32(i)
    83  	}
    84  	for i := range permutation {
    85  		j := rand.Intn(count)
    86  		temp := permutation[i]
    87  		permutation[i] = permutation[j]
    88  		permutation[j] = temp
    89  	}
    90  	return permutation
    91  }
    92  
    93  func Gen_R(count int) []crypto2.Key {
    94  	R := make([]crypto2.Key, count)
    95  	for i := range R {
    96  		R[i] = crypto2.SkGen()
    97  	}
    98  	return R
    99  }
   100  
   101  func Shuffle_gen_with_regulation(m, n int, inputs []crypto2.Key,
   102  	permutation []int32, R []crypto2.Key) (outputs []crypto2.Key, proof []byte) {
   103  	if m*n != len(inputs) || m*n != len(permutation) || m*n != len(R) {
   104  		return
   105  	}
   106  	_inputs := make([]byte, len(inputs)*crypto2.KeyLength)
   107  	for i := range inputs {
   108  		copy(_inputs[i*crypto2.KeyLength:(i+1)*crypto2.KeyLength], inputs[i][:])
   109  	}
   110  	_R := make([]byte, len(R)*crypto2.KeyLength)
   111  	for i := range R {
   112  		copy(_R[i*crypto2.KeyLength:(i+1)*crypto2.KeyLength], R[i][:])
   113  	}
   114  	var _outputs, _proof *C.char
   115  	var _outputsLen, _proofLen int32
   116  	C.shuffle_gen_with_regulation((*C.char)(unsafe.Pointer(&_inputs[0])), (C.int)(m), (C.int)(n),
   117  		(**C.char)(unsafe.Pointer(&_outputs)), (*C.int)(unsafe.Pointer(&_outputsLen)),
   118  		(**C.char)(unsafe.Pointer(&_proof)), (*C.int)(unsafe.Pointer(&_proofLen)),
   119  		(*C.int)(unsafe.Pointer(&permutation[0])), (*C.char)(unsafe.Pointer(&_R[0])))
   120  	if _outputs == nil || _proof == nil || _outputsLen == 0 || _proofLen == 0 {
   121  		return
   122  	}
   123  	defer C.deleteCharArray(_outputs)
   124  	defer C.deleteCharArray(_proof)
   125  
   126  	var outputsSlice []byte // can only be used in this function, once getting outside, its data will be freed.
   127  	toSlice(unsafe.Pointer(_outputs), unsafe.Pointer(&outputsSlice), int(_outputsLen*crypto2.KeyLength))
   128  	defer eraseSlice(unsafe.Pointer(&outputsSlice))
   129  	outputs = make([]crypto2.Key, _outputsLen)
   130  	for i := range outputs {
   131  		copy(outputs[i][:], outputsSlice[i*crypto2.KeyLength:(i+1)*crypto2.KeyLength])
   132  	}
   133  
   134  	var proofSlice []byte
   135  	toSlice(unsafe.Pointer(_proof), unsafe.Pointer(&proofSlice), int(_proofLen))
   136  	defer eraseSlice(unsafe.Pointer(&proofSlice))
   137  	proof = make([]byte, _proofLen)
   138  	copy(proof, proofSlice[:])
   139  
   140  	return
   141  }
   142  
   143  func Shuffle_ver(m, n int, inputs []crypto2.Key, outputs []crypto2.Key, proof []byte) bool {
   144  	if m*n != len(inputs) {
   145  		return false
   146  	}
   147  	_inputs := make([]byte, len(inputs)*crypto2.KeyLength)
   148  	for i := range inputs {
   149  		copy(_inputs[i*crypto2.KeyLength:(i+1)*crypto2.KeyLength], inputs[i][:])
   150  	}
   151  
   152  	_outputs := make([]byte, len(outputs)*crypto2.KeyLength)
   153  	for i := range outputs {
   154  		copy(_outputs[i*crypto2.KeyLength:(i+1)*crypto2.KeyLength], outputs[i][:])
   155  	}
   156  
   157  	ret, _ := C.shuffle_ver((*C.char)(unsafe.Pointer(&_inputs[0])), (C.int)(m), (C.int)(n),
   158  		(*C.char)(unsafe.Pointer(&_outputs[0])), (C.int)(len(outputs)),
   159  		(*C.char)(unsafe.Pointer(&proof[0])), (C.int)(len(proof)))
   160  
   161  	if ret != 1 {
   162  		return false
   163  	}
   164  	return true
   165  }