Exemple #1
0
func (v *VirStorageVol) Download(stream *VirStream, offset, length uint64, flags uint32) error {
	if C.virStorageVolDownload(v.ptr, stream.ptr, C.ulonglong(offset),
		C.ulonglong(length), C.uint(flags)) == -1 {
		return GetLastError()
	}
	return nil
}
Exemple #2
0
// sign data with secret key sk
// return detached sig
// this uses crypto_sign instead pf crypto_sign_detached
func CryptoSignFucky(msg, sk []byte) []byte {
	msgbuff := NewBuffer(msg)
	defer msgbuff.Free()
	skbuff := NewBuffer(sk)
	defer skbuff.Free()
	if skbuff.size != C.crypto_sign_bytes() {
		log.Println("nacl.CryptoSign() invalid secret key size", len(sk))
		return nil
	}

	// allocate the signed message buffer
	sig := malloc(C.crypto_sign_bytes() + msgbuff.size)
	defer sig.Free()
	// compute signature
	siglen := C.ulonglong(0)
	res := C.crypto_sign(sig.uchar(), &siglen, msgbuff.uchar(), C.ulonglong(msgbuff.size), skbuff.uchar())
	if res == 0 {
		// return copy of signature inside the signed message
		offset := int(C.crypto_sign_bytes())
		return sig.Bytes()[:offset]
	}
	// failure to sign
	log.Println("nacl.CryptoSign() failed")
	return nil
}
Exemple #3
0
func StorageVolUpload(vol VirStorageVol, s VirStream, offset uint64, length uint64) error {

	result := C.virStorageVolUpload(vol.ptr, s.ptr, C.ulonglong(offset), C.ulonglong(length), 0)
	if result < 0 {
		return errors.New(GetLastError())
	}
	return nil
}
Exemple #4
0
func (ctx *natrAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
	out := make([]byte, len(plaintext)+_AEADOverheadBytes)
	rv := C.crypto_aead_chacha20poly1305_encrypt(g2cbt(out), nil,
		g2cbt(plaintext), C.ulonglong(len(plaintext)), g2cbt(data), C.ulonglong(len(data)),
		nil, g2cbt(nonce), g2cbt(ctx.key[:]))
	if rv != 0 {
		panic("crypto_secretbox_easy returned non-zero")
	}
	return append(dst, out...)
}
Exemple #5
0
func (ctx *natrAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
	out := make([]byte, len(ciphertext)-_AEADOverheadBytes)
	rv := C.crypto_aead_chacha20poly1305_decrypt(g2cbt(out), nil, nil,
		g2cbt(ciphertext), C.ulonglong(len(ciphertext)), g2cbt(data), C.ulonglong(len(data)),
		g2cbt(nonce), g2cbt(ctx.key[:]))
	if rv != 0 {
		return nil, errors.New("MAC error")
	}
	return append(dst, out...), nil
}
Exemple #6
0
func lowerWindow(c1 chan string, cycles int64) {
	C.init_perfcounters(1, 0)
	timeStart := C.ulonglong(C.get_cyclecount())
	for {
		timeElapsed := C.ulonglong(C.get_cyclecount()) - timeStart
		if timeElapsed > C.ulonglong(cycles) {
			c1 <- "ENTER WINDOW\n"
			break
		}
	}
}
Exemple #7
0
func big2scalar(out *[4]C.ulonglong, in *big.Int) error {
	b := in.Bits()
	if len(b) > 8 {
		return fmt.Errorf("big.Int needs %d words, cannot be converted to scalar_t", len(b))
	}
	max := len(b) >> 1
	for i := 0; i < max; i++ {
		out[i] = C.ulonglong(b[i<<1]) | (C.ulonglong(b[i<<1+1]) << 32)
	}
	if len(b)&0x1 == 1 {
		out[max] = C.ulonglong(b[len(b)-1])
	}
	return nil
}
Exemple #8
0
//export ReadMsgpackFrame
//
// ReadMsgpackFrame reads the msgpack frame at byteOffset in rawStream, decodes the
// 2-5 bytes of a msgpack binary array (either bin8, bin16, or bin32), and returns
// and the decoded-into-R object and the next byteOffset to use.
//
func ReadMsgpackFrame(rawStream C.SEXP, byteOffset C.SEXP) C.SEXP {

	var start int
	if C.TYPEOF(byteOffset) == C.REALSXP {
		start = int(C.get_real_elt(byteOffset, 0))
	} else if C.TYPEOF(byteOffset) == C.INTSXP {
		start = int(C.get_int_elt(byteOffset, 0))
	} else {
		C.ReportErrorToR_NoReturn(C.CString("read.msgpack.frame(x, byteOffset) requires byteOffset to be a numeric byte-offset number."))
	}

	// rawStream must be a RAWSXP
	if C.TYPEOF(rawStream) != C.RAWSXP {
		C.ReportErrorToR_NoReturn(C.CString("read.msgpack.frame(x, byteOffset) requires x be a RAW vector of bytes."))
	}

	n := int(C.Rf_xlength(rawStream))
	if n == 0 {
		return C.R_NilValue
	}

	if start >= n {
		C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("read.msgpack.frame(x, byteOffset) error: byteOffset(%d) is beyond the length of x (x has len %d).", start, n)))
	}

	var decoder [5]byte
	C.memcpy(unsafe.Pointer(&decoder[0]), unsafe.Pointer(C.get_raw_elt_ptr(rawStream, C.ulonglong(start))), C.size_t(5))
	headerSz, _, totalSz, err := DecodeMsgpackBinArrayHeader(decoder[:])
	if err != nil {
		C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("ReadMsgpackFrame error trying to decode msgpack frame: %s", err)))
	}

	if start+totalSz > n {
		C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("read.msgpack.frame(x, byteOffset) error: byteOffset(%d) plus the frames size(%d) goes beyond the length of x (x has len %d).", start, totalSz, n)))
	}

	bytes := make([]byte, totalSz)
	C.memcpy(unsafe.Pointer(&bytes[0]), unsafe.Pointer(C.get_raw_elt_ptr(rawStream, C.ulonglong(start))), C.size_t(totalSz))

	rObject := decodeMsgpackToR(bytes[headerSz:])
	C.Rf_protect(rObject)
	returnList := C.allocVector(C.VECSXP, C.R_xlen_t(2))
	C.Rf_protect(returnList)
	C.SET_VECTOR_ELT(returnList, C.R_xlen_t(0), C.Rf_ScalarReal(C.double(float64(start+totalSz))))
	C.SET_VECTOR_ELT(returnList, C.R_xlen_t(1), rObject)
	C.Rf_unprotect_ptr(rObject)
	C.Rf_unprotect_ptr(returnList)
	return returnList
}
Exemple #9
0
// verify a signed message
func CryptoVerify(smsg, pk []byte) bool {
	smsg_buff := NewBuffer(smsg)
	defer smsg_buff.Free()
	pk_buff := NewBuffer(pk)
	defer pk_buff.Free()

	if pk_buff.size != C.crypto_sign_publickeybytes() {
		return false
	}
	mlen := C.ulonglong(0)
	msg := malloc(C.size_t(len(smsg)))
	defer msg.Free()
	smlen := C.ulonglong(smsg_buff.size)
	return C.crypto_sign_open(msg.uchar(), &mlen, smsg_buff.uchar(), smlen, pk_buff.uchar()) != -1
}
Exemple #10
0
func waitTimer(cycles int64, f *os.File) int {
	// init counters:
	C.init_perfcounters(1, 0)
	//fmt.Printf("cyles to wait: %d\n", cycles)
	timeStart := C.ulonglong(C.get_cyclecount())
	timeElapsed := C.ulonglong(0)
	for {
		timeElapsed = C.ulonglong(C.get_cyclecount()) - timeStart
		if timeElapsed > C.ulonglong(cycles) {
			writeMessage(f, fmt.Sprintf("%27s", "COMPLETE"))
			break
		}
	}
	return int(timeElapsed)
}
Exemple #11
0
// encrypts a message to a user given their public key is known
// returns an encrypted box
func CryptoBox(msg, nounce, pk, sk []byte) []byte {
	msgbuff := NewBuffer(msg)
	defer msgbuff.Free()

	// check sizes
	if len(pk) != int(C.crypto_box_publickeybytes()) {
		log.Println("len(pk) != crypto_box_publickey_bytes")
		return nil
	}
	if len(sk) != int(C.crypto_box_secretkeybytes()) {
		log.Println("len(sk) != crypto_box_secretkey_bytes")
		return nil
	}
	if len(nounce) != int(C.crypto_box_macbytes()) {
		log.Println("len(nounce) != crypto_box_macbytes()")
		return nil
	}

	pkbuff := NewBuffer(pk)
	defer pkbuff.Free()
	skbuff := NewBuffer(sk)
	defer skbuff.Free()
	nouncebuff := NewBuffer(nounce)
	defer nouncebuff.Free()

	resultbuff := malloc(msgbuff.size + nouncebuff.size)
	defer resultbuff.Free()
	res := C.crypto_box_easy(resultbuff.uchar(), msgbuff.uchar(), C.ulonglong(msgbuff.size), nouncebuff.uchar(), pkbuff.uchar(), skbuff.uchar())
	if res != 0 {
		log.Println("crypto_box_easy failed:", res)
		return nil
	}
	return resultbuff.Bytes()
}
Exemple #12
0
// New returns a new Pigosat instance, ready to have literals added to it. The
// error return value need only be checked if the OutputFile option is non-nil.
func New(options *Options) (*Pigosat, error) {
	// PicoSAT * picosat_init (void);
	p := C.picosat_init()
	if options != nil {
		// void picosat_set_propagation_limit (PicoSAT *, unsigned long long limit);
		C.picosat_set_propagation_limit(p, C.ulonglong(options.PropagationLimit))
		if options.OutputFile != nil {
			cfile, err := cfdopen(options.OutputFile, "a")
			if err != nil {
				C.picosat_reset(p)
				return nil, &os.PathError{Op: "fdopen",
					Path: options.OutputFile.Name(), Err: err}
			}
			// void picosat_set_output (PicoSAT *, FILE *);
			C.picosat_set_output(p, cfile)
		}
		// void picosat_set_verbosity (PicoSAT *, int new_verbosity_level);
		C.picosat_set_verbosity(p, C.int(options.Verbosity))
		if options.Prefix != "" {
			// void picosat_set_prefix (PicoSAT *, const char *);
			prefix := C.CString(options.Prefix)
			defer C.free(unsafe.Pointer(prefix))
			C.picosat_set_prefix(p, prefix)
		}
		if options.MeasureAllCalls {
			// void picosat_measure_all_calls (PicoSAT *);
			C.picosat_measure_all_calls(p)
		}
	}
	pgo := &Pigosat{p: p, lock: sync.RWMutex{}}
	runtime.SetFinalizer(pgo, (*Pigosat).delete)
	return pgo, nil
}
func Random(n int) []byte {
	buf := make([]byte, n)

	C.randombytes(array(buf), C.ulonglong(n))

	return buf
}
Exemple #14
0
// open an encrypted box
func CryptoBoxOpen(box, nounce, sk, pk []byte) ([]byte, error) {
	boxbuff := NewBuffer(box)
	defer boxbuff.Free()

	// check sizes
	if len(pk) != int(C.crypto_box_publickeybytes()) {
		err := errors.New("len(pk) != crypto_box_publickey_bytes")
		return nil, err
	}
	if len(sk) != int(C.crypto_box_secretkeybytes()) {
		err := errors.New("len(sk) != crypto_box_secretkey_bytes")
		return nil, err
	}
	if len(nounce) != int(C.crypto_box_macbytes()) {
		err := errors.New("len(nounce) != crypto_box_macbytes()")
		return nil, err
	}

	pkbuff := NewBuffer(pk)
	defer pkbuff.Free()
	skbuff := NewBuffer(sk)
	defer skbuff.Free()
	nouncebuff := NewBuffer(nounce)
	defer nouncebuff.Free()
	resultbuff := malloc(boxbuff.size - nouncebuff.size)
	defer resultbuff.Free()

	// decrypt
	res := C.crypto_box_open_easy(resultbuff.uchar(), boxbuff.uchar(), C.ulonglong(boxbuff.size), nouncebuff.uchar(), pkbuff.uchar(), skbuff.uchar())
	if res != 0 {
		return nil, errors.New("crypto_box_open_easy failed")
	}
	// return result
	return resultbuff.Bytes(), nil
}
func Hash(message []byte) []byte {
	hash := make([]byte, HashSize)

	C.crypto_hash(array(hash), array(message), C.ulonglong(len(message)))

	return hash
}
Exemple #16
0
// takes as input a public key and a signed message
// returns whether the signature is valid or not
func Verify(verificationKey PublicKey, signedMessage SignedMessage) (verified bool, err error) {
	// points to unsigned message after verifying
	var messagePointer *C.uchar
	messageBytes := make([]byte, len(signedMessage.Message)+1)
	if len(signedMessage.Message) == 0 {
		// must point somewhere valid, but the data won't be altered
		// can't point to [0] because the slice is empty
		messagePointer = (*C.uchar)(unsafe.Pointer(&messageBytes))
	} else {
		messagePointer = (*C.uchar)(unsafe.Pointer(&messageBytes[0]))
	}

	// points to an int so the C function can return the message length after verifying
	var messageLen uint64
	lenPointer := (*C.ulonglong)(unsafe.Pointer(&messageLen))

	// points to the signed message as input for verification
	signedMessageBytes := []byte(signedMessage.CombinedMessage())
	signedMessagePointer := (*C.uchar)(unsafe.Pointer(&signedMessageBytes[0]))

	// length of signed message, but as a C object
	signedMessageLen := C.ulonglong(len(signedMessageBytes))

	// pointer to the public key used to sign the message
	verificationKeyPointer := (*C.uchar)(unsafe.Pointer(&verificationKey[0]))

	// verify signature
	success := C.crypto_sign_open(messagePointer, lenPointer, signedMessagePointer, signedMessageLen, verificationKeyPointer)
	verified = success == 0
	return
}
Exemple #17
0
func (v *VirStorageVol) Resize(capacity uint64, flags uint32) error {
	result := C.virStorageVolResize(v.ptr, C.ulonglong(capacity), C.uint(flags))
	if result == -1 {
		return GetLastError()
	}
	return nil
}
Exemple #18
0
func (lua *Lua) PushGoValue(value reflect.Value) {
	switch t := value.Type(); t.Kind() {
	case reflect.Bool:
		if value.Bool() {
			C.lua_pushboolean(lua.State, C.int(1))
		} else {
			C.lua_pushboolean(lua.State, C.int(0))
		}
	case reflect.String:
		C.lua_pushstring(lua.State, C.CString(value.String()))
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		C.lua_pushnumber(lua.State, C.lua_Number(C.longlong(value.Int())))
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		C.lua_pushnumber(lua.State, C.lua_Number(C.ulonglong(value.Uint())))
	case reflect.Float32, reflect.Float64:
		C.lua_pushnumber(lua.State, C.lua_Number(C.double(value.Float())))
	case reflect.Slice:
		length := value.Len()
		C.lua_createtable(lua.State, C.int(length), 0)
		for i := 0; i < length; i++ {
			C.lua_pushnumber(lua.State, C.lua_Number(i+1))
			lua.PushGoValue(value.Index(i))
			C.lua_settable(lua.State, -3)
		}
	case reflect.Interface:
		lua.PushGoValue(value.Elem())
	case reflect.Ptr, reflect.UnsafePointer:
		C.lua_pushlightuserdata(lua.State, unsafe.Pointer(value.Pointer()))
	default:
		lua.Panic("wrong return value %v %v", value, t.Kind())
	}
}
Exemple #19
0
// Start will compile `program` and return a three channels: input, output and
// error. Sending a jq.Jv* to input cause the program to be run to it and
// one-or-more results returned as jq.Jv* on the output channel, or one or more
// error values sent to the error channel. When you are done sending values
// close the input channel.
//
// args is a list of key/value pairs to bind as variables into the program, and
// must be an array type even if empty. Each element of the array should be an
// object with a "name" and "value" properties. Name should exclude the "$"
// sign. For example this is `[ {"name": "n", "value": 1 } ]` would then be
// `$n` in the programm.
//
// This function is not reentereant -- in that you cannot and should not call
// Start again until you have closed the previous input channel.
//
// If there is a problem compiling the JQ program then the errors will be
// reported on error channel before any input is read so makle sure you account
// for this case.
//
// Any jq.Jv* values passed to the input channel will be owned by the channel.
// If you want to keep them afterwards ensure you Copy() them before passing to
// the channel
func (jq *Jq) Start(program string, args *Jv) (in chan<- *Jv, out <-chan *Jv, errs <-chan error) {
	// Create out two way copy of the channels. We need to be able to recv from
	// input, so need to store the original channel
	cIn := make(chan *Jv)
	cOut := make(chan *Jv)
	cErr := make(chan error)

	// And assign the read/write only versions to the output fars
	in = cIn
	out = cOut
	errs = cErr

	// Before setting up any of the global error handling state, lets check that
	// args is of the right type!
	if args.Kind() != JV_KIND_ARRAY {
		go func() {
			// Take ownership of the inputs
			for jv := range cIn {
				jv.Free()
			}
			cErr <- fmt.Errorf("`args` parameter is of type %s not array!", args.Kind().String())
			args.Free()
			close(cOut)
			close(cErr)
		}()
		return
	}

	jq.errorStoreId = globalErrorChannels.Add(cErr)

	// Because we can't pass a function pointer to an exported Go func we have to
	// call a C function which uses the exported fund for us.
	// https://github.com/golang/go/wiki/cgo#function-variables
	C.install_jq_error_cb(jq._state, C.ulonglong(jq.errorStoreId))

	go func() {

		if jq._Compile(program, args) == false {
			// Even if compile failed follow the contract. Read any inputs and take
			// ownership of them (aka free them)
			//
			// Errors from compile will be sent to the error channel
			for jv := range cIn {
				jv.Free()
			}
		} else {
			for jv := range cIn {
				jq._Execute(jv, cOut, cErr)
			}
		}
		// Once we've read all the inputs close the output to signal to caller that
		// we are done.
		close(cOut)
		close(cErr)
		C.install_jq_error_cb(jq._state, 0)
	}()

	return
}
Exemple #20
0
func newPlatformInfo(tune TuneFlag, cpu CpuFeature) *hsPlatformInfo {
	var platform C.struct_hs_platform_info

	platform.tune = C.uint(tune)
	platform.cpu_features = C.ulonglong(cpu)

	return &hsPlatformInfo{platform}
}
func (b Boxer) Box(message []byte, nonce []byte) []byte {
	result := make([]byte, C.crypto_box_ZEROBYTES+len(message))

	copy(result[C.crypto_box_ZEROBYTES:], message)

	C.crypto_box_afternm(array(result), array(result), C.ulonglong(len(result)), array(nonce), array(b))

	return result[C.crypto_box_BOXZEROBYTES:]
}
func Box(message []byte, nonce Nonce, pk PublicKey, sk SecretKey) []byte {
	result := make([]byte, C.crypto_box_ZEROBYTES+len(message))

	copy(result[C.crypto_box_ZEROBYTES:], message)

	C.crypto_box(array(result), array(result), C.ulonglong(len(result)), array(nonce), array(pk), array(sk))

	return result[C.crypto_box_BOXZEROBYTES:]
}
Exemple #23
0
func test6833(t *testing.T) {
	ui := 7
	ull := uint64(0x4000300020001000)
	v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull)))
	exp := uint64(ui) + ull
	if v != exp {
		t.Errorf("issue6833Func() returns %x, expected %x", v, exp)
	}
}
Exemple #24
0
//export ReadNewlineDelimJson
//
// ReadNewlineDelimJson reads a json object at byteOffset in rawStream, expects
// it to be newline terminated, and returns the
// decoded-into-R object and the next byteOffset to use (the byte just after
// the terminating newline).
//
func ReadNewlineDelimJson(rawStream C.SEXP, byteOffset C.SEXP) C.SEXP {
	C.Rf_protect(rawStream)

	var start int
	if C.TYPEOF(byteOffset) == C.REALSXP {
		start = int(C.get_real_elt(byteOffset, 0))
	} else if C.TYPEOF(byteOffset) == C.INTSXP {
		start = int(C.get_int_elt(byteOffset, 0))
	} else {
		C.ReportErrorToR_NoReturn(C.CString("read.ndjson(x, byteOffset) requires byteOffset to be a numeric byte-offset number."))
	}
	// rawStream must be a RAWSXP
	if C.TYPEOF(rawStream) != C.RAWSXP {
		C.ReportErrorToR_NoReturn(C.CString("read.ndjson(x, byteOffset) requires x be a RAW vector of bytes."))
	}

	n := int(C.Rf_xlength(rawStream))
	if n == 0 {
		return C.R_NilValue
	}

	if start >= n {
		C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("read.ndjson(x, byteOffset) error: byteOffset(%d) is at or beyond the length of x (x has len %d).", start, n)))
	}
	// INVAR: start < n

	// find the next newline or end of raw array
	next := int(C.next_newline_pos(rawStream, C.ulonglong(start+1), C.ulonglong(n)))
	totalSz := next - start

	bytes := make([]byte, totalSz)
	fromPtr := unsafe.Pointer(C.get_raw_elt_ptr(rawStream, C.ulonglong(start)))
	C.memcpy(unsafe.Pointer(&bytes[0]), fromPtr, C.size_t(totalSz))
	rObject := decodeJsonToR(bytes)
	C.Rf_protect(rObject)
	returnList := C.allocVector(C.VECSXP, C.R_xlen_t(2))
	C.Rf_protect(returnList)
	C.SET_VECTOR_ELT(returnList, C.R_xlen_t(0), C.Rf_ScalarReal(C.double(float64(start+totalSz))))
	C.SET_VECTOR_ELT(returnList, C.R_xlen_t(1), rObject)
	C.Rf_unprotect_ptr(rObject)
	C.Rf_unprotect_ptr(returnList)
	C.Rf_unprotect_ptr(rawStream)
	return returnList
}
Exemple #25
0
func big2scalar(out *[4]C.ulonglong, in *big.Int) error {
	b := in.Bits()
	if len(b) > 4 {
		return fmt.Errorf("big.Int needs %d words, cannot be converted to scalar_t", len(b))
	}
	for i, w := range b {
		out[i] = C.ulonglong(w)
	}
	return nil
}
Exemple #26
0
func newClientID() (*C.h, error) {
	buf := make([]byte, 16)
	if _, err := rng.Read(buf[:]); err != nil {
		return nil, err
	}
	buf[8] = (buf[8] | 0x40) & 0x7F
	buf[6] = (buf[6] & 0xF) | (4 << 4)
	u, _ := binary.Uvarint(buf)
	return C.new_client_id(C.ulonglong(u)), nil
}
Exemple #27
0
func (t *TypedParameters) TypedParamsAddUInt64(val uint64, name string) error {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	result := C.virTypedParamsAddULLong(&t.cptr, &t.length, &t.capacity, cname, C.ulonglong(val))
	if result == -1 {
		return GetLastError()
	}
	return nil
}
func OneTimeAuth(message []byte, key []byte) []byte {
	if len(key) != OneTimeAuthKeySize {
		panic(fmt.Sprintf("Key is wrong size; expected it to be %d", C.crypto_onetimeauth_KEYBYTES))
	}

	auth := make([]byte, C.crypto_onetimeauth_BYTES)

	C.crypto_onetimeauth(array(auth), array(message), C.ulonglong(len(message)), array(key))

	return auth
}
Exemple #29
0
// Uses the hash in libsodium
func CalculateHash(data []byte) (hash Hash, err error) {
	hashPointer := (*C.uchar)(unsafe.Pointer(&hash[0]))
	messagePointer := (*C.uchar)(unsafe.Pointer(&data[0]))
	sizeOfMessage := C.ulonglong(len(data))
	success := C.crypto_hash(hashPointer, messagePointer, sizeOfMessage)
	if success != 0 {
		err = fmt.Errorf("Error in calculating hash")
	}

	return
}
func (b Boxer) Unbox(box []byte, nonce []byte) ([]byte, error) {
	result := make([]byte, C.crypto_box_BOXZEROBYTES+len(box))

	copy(result[C.crypto_box_BOXZEROBYTES:], box)

	code := C.crypto_box_open_afternm(array(result), array(result), C.ulonglong(len(result)), array(nonce), array(b))

	if code == 0 {
		return result[C.crypto_box_ZEROBYTES:], nil
	} else {
		return nil, ErrBoxOpen
	}
}