149 lines
3.4 KiB
Go
149 lines
3.4 KiB
Go
package rln
|
|
|
|
/*
|
|
#include "./librln.h"
|
|
*/
|
|
import "C"
|
|
import (
|
|
"errors"
|
|
"unsafe"
|
|
)
|
|
|
|
// RLN represents the context used for rln.
|
|
type RLN struct {
|
|
ptr *C.RLN
|
|
}
|
|
|
|
func toCBufferPtr(input []byte) *C.Buffer {
|
|
buf := toBuffer(input)
|
|
|
|
size := int(unsafe.Sizeof(buf))
|
|
in := (*C.Buffer)(C.malloc(C.size_t(size)))
|
|
*in = buf
|
|
|
|
return in
|
|
}
|
|
|
|
// toBuffer converts the input to a buffer object that is used to communicate data with the rln lib
|
|
func toBuffer(data []byte) C.Buffer {
|
|
dataPtr, dataLen := sliceToPtr(data)
|
|
return C.Buffer{
|
|
ptr: dataPtr,
|
|
len: C.uintptr_t(dataLen),
|
|
}
|
|
}
|
|
|
|
func sliceToPtr(slice []byte) (*C.uchar, C.int) {
|
|
if len(slice) == 0 {
|
|
return nil, 0
|
|
} else {
|
|
return (*C.uchar)(unsafe.Pointer(&slice[0])), C.int(len(slice))
|
|
}
|
|
}
|
|
|
|
func NewWithParams(depth int, wasm []byte, zkey []byte, verifKey []byte) (*RLN, error) {
|
|
wasmBuffer := toCBufferPtr(wasm)
|
|
zkeyBuffer := toCBufferPtr(zkey)
|
|
verifKeyBuffer := toCBufferPtr(verifKey)
|
|
r := &RLN{}
|
|
|
|
if !bool(C.new_with_params(C.uintptr_t(depth), wasmBuffer, zkeyBuffer, verifKeyBuffer, &r.ptr)) {
|
|
return nil, errors.New("failed to initialize")
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
func NewWithFolder(depth int, resourcesFolderPath string) (*RLN, error) {
|
|
r := &RLN{}
|
|
pathBuffer := toCBufferPtr([]byte(resourcesFolderPath))
|
|
if !bool(C.new(C.uintptr_t(depth), pathBuffer, &r.ptr)) {
|
|
return nil, errors.New("failed to initialize")
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
func (r *RLN) ExtendedKeyGen() []byte {
|
|
buffer := toBuffer([]byte{})
|
|
if !bool(C.extended_key_gen(r.ptr, &buffer)) {
|
|
return nil
|
|
}
|
|
return C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len))
|
|
}
|
|
|
|
func (r *RLN) Hash(input []byte) ([]byte, error) {
|
|
inpBuff := toCBufferPtr(input)
|
|
|
|
var output []byte
|
|
out := toBuffer(output)
|
|
|
|
if !bool(C.hash(inpBuff, &out)) {
|
|
return nil, errors.New("failed to hash")
|
|
}
|
|
|
|
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
|
|
}
|
|
|
|
func (r *RLN) PoseidonHash(input []byte) ([]byte, error) {
|
|
inpBuff := toCBufferPtr(input)
|
|
|
|
var output []byte
|
|
out := toBuffer(output)
|
|
|
|
if !bool(C.poseidon_hash(inpBuff, &out)) {
|
|
return nil, errors.New("error in poseidon hash")
|
|
}
|
|
|
|
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
|
|
}
|
|
|
|
func (r *RLN) GenerateRLNProof(input []byte) ([]byte, error) {
|
|
inputBuffer := toCBufferPtr(input)
|
|
|
|
var output []byte
|
|
out := toBuffer(output)
|
|
|
|
if !bool(C.generate_rln_proof(r.ptr, inputBuffer, &out)) {
|
|
return nil, errors.New("could not generate the proof")
|
|
}
|
|
|
|
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
|
|
}
|
|
|
|
func (r *RLN) VerifyWithRoots(input []byte, roots []byte) (bool, error) {
|
|
proofBuf := toCBufferPtr(input)
|
|
rootBuf := toCBufferPtr(roots)
|
|
|
|
res := C.bool(false)
|
|
if !bool(C.verify_with_roots(r.ptr, proofBuf, rootBuf, &res)) {
|
|
return false, errors.New("could not verify with roots")
|
|
}
|
|
|
|
return bool(res), nil
|
|
}
|
|
|
|
func (r *RLN) SetNextLeaf(idcommitment []byte) bool {
|
|
buff := toCBufferPtr(idcommitment[:])
|
|
return bool(C.set_next_leaf(r.ptr, buff))
|
|
}
|
|
|
|
func (r *RLN) SetLeavesFrom(index uint, idcommitments []byte) bool {
|
|
idCommBuffer := toCBufferPtr(idcommitments)
|
|
return bool(C.set_leaves_from(r.ptr, C.uintptr_t(index), idCommBuffer))
|
|
}
|
|
|
|
func (r *RLN) DeleteLeaf(index uint) bool {
|
|
return bool(C.delete_leaf(r.ptr, C.uintptr_t(index)))
|
|
}
|
|
|
|
func (r *RLN) GetRoot() ([]byte, error) {
|
|
var output []byte
|
|
out := toBuffer(output)
|
|
|
|
if !bool(C.get_root(r.ptr, &out)) {
|
|
return nil, errors.New("could not get the root")
|
|
}
|
|
|
|
return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil
|
|
}
|